Re: Is there a way to exclude user-specified files or directories from participating in merges?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2009-02-18, Junio C Hamano <gitster@xxxxxxxxx> wrote:
> Sitaram Chamarty <sitaramc@xxxxxxxxx> writes:
>
> > Let me explain where I'm coming from: this is very often needed when you
> > maintain customer specific branches, and the workflows in both your
> > posts in this thread so far are too complex for, err, me <sheepish grin>
> > :-)
> >
> > Would it not be easier to do something like this?  (I suck at 2-d
> > drawing, even line... but this should still be understandable)
> 
> What you drew is a detailed discussion on a technique to use to group
> together common part and customer specific part, and I think it is Ok to
> do whatever you feel comfortable with.  It is essentially the same as my
> "in real life, 'git diff >P.diff' is not how I would do this" example,
> just going into more detail on what you would do to sift 'common only' vs
> 'specific to work branch' apart, and I think what you are doing is sane.

Thanks -- I mainly wanted confirmation that one does *not*
have to do diff/patch/apply or plumbing commands to achieve
what the original poster was asking.

> But if you wrote it as a draft of a document to explain how-to to new
> people, I think you need to clarify a few things.

> It is unclear in your description how the "common" branch progressed in
> the whole process, and how the resulting history looks.  I can guess that
> you meant commits marked with alphabet letters are of common kind and
> numbers are of work kind, but you do not want to force readers to guess.

> It also is not quite clear that you are using a temporary branch in
> addition to common and work, and where in your sequence you are doing "git
> checkout" to switch branches.

I did not write it in that light then, but I will do so now,
and if you have a few minutes to critique it that would be
great.  If it's crap, sorry for the noise.

----->8-----

The following document explains how to maintain a 'common'
branch, with one or more 'customer specific' branches that
hang off of the common branch.  The inspiration was a
question about maintaining 'work' and 'home' configurations
which differ perhaps slightly from a 'common' configuration,
which leads to the same sort of situation.

The basic rules are best described by Junio in
http://permalink.gmane.org/gmane.comp.version-control.git/110489

>  - You make edits to common files only on the common branch.
>  - You merge from common to deployment, never the other way.

This is one way to follow those rules.

We use the following terminology:

'common' is the branch representing the base product.  All
regular customers get this version.

'special' is a special branch for a specific customer.  This
customer needs changes unique to his environment, which
should not be merged back into the common branch.  However,
this branch must regularly get the benefit of changes in the
mainline 'common' branch.  (This is the genesis of the two
rules above).

If you have more than one special customer the same logic
will apply for each of them separately, although if you have
too many such customers you may also want to look at "Never
merging back" (http://gitster.livejournal.com/26540.html)
for an additional tip on this.

Also, we assume the actual development and testing needs to
be done on one branch, so you will have a mix of 'common'
and 'special' changes all together.

The history looks like this in the beginning:

    -----o          <- special branch (current)
        /
    ---o            <- common branch

Before you start, make a temporary branch TEMP from
'special'; leave special where it was.

    git checkout -b TEMP special

You now make some changes for the special customer, which
also involve some 'common' changes that need to be ported
back to the common branch.  The topology now looks like
this, where A, B, C, are changes that logically belong on
'common', and 1, 2, 3, are changes that are specific to this
customer.

Notice that the 2 sets of changes are intermixed because
that is how the development happened, and that there is even
one commit where common and special changes are mixed
(perhaps you realised this only later).

    -----o--A--B1--2--3--C          <- "TEMP" branch (current)
        /
    ---o                            <- common

Meanwhile, just to make things interesting, the common
branch has also had some other, unrelated changes which you
eventually want on the special branch as well.

    -----o--A--B1--2--3--C          <- "TEMP" branch (current)
        /                                            
    ---o--X--Y                      <- common

The first thing to do is to tease the tangled commits apart
using rebase.

Using 'git rebase -i special', get the topology into this
shape.  Note that we have split the "B1" commit into B and 1
separately.  'git help rebase' has a very simple and clear
section on splitting commits, so I will not detail that
here.

    -----o--A--B--C--1--2--3        <- "TEMP" branch (current)
        /                                              
    ---o--X--Y                      <- common

At this point you may want to retest, just to be sure.

Now switch to the 'common' branch and cherry pick the
changes that belong on 'common'.  The simplest way to cherry
pick is gitk.

    git checkout common
    gitk
    # and cherry pick first A, then B, then C, in order

    -----o--A--B--C--1--2--3        <- "TEMP" branch
        /                                              
    ---o--X--Y--A'--B'--C'          <- common (current)

Now merge from 'common' to 'special'

    git checkout special
    git merge common

           A--B--C--1--2--3     <- TEMP
          /
     ----o-----------------o    <- special (current)
        /                 /
    ---o--X--Y--A'--B'--C'

Now all we need is to get commits 1, 2, and 3 onto
'special'; this is easiest done by rebasing TEMP first...

    git rebase special TEMP

                             1'--2'--3'     <- TEMP (current)
                            /
     ----o-----------------o    <- special
        /                 /
    ---o--X--Y--A'--B'--C'

...and then making special equal to TEMP

    git checkout special
    git merge TEMP

                             1'--2'--3'     <- special (current)
                            /
     ----o-----------------o
        /                 /
    ---o--X--Y--A'--B'--C'

Now you don't need TEMP anymore, and can delete it:

    git branch -d TEMP


--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux