git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Dowlin Yang <dowlin0820@gmail.com>
To: Jan Hudec <bulb@ucw.cz>
Cc: git@vger.kernel.org
Subject: Re: how git pull works?
Date: Sat, 20 Nov 2010 09:18:53 +0800	[thread overview]
Message-ID: <BBB0EEDC-25DC-4DB6-8923-762986FC07B0@gmail.com> (raw)
In-Reply-To: <20101119212729.GH30870@efreet.light.src>

Hi Bulb

Now I totally got it. Thanks very much for the explanation!

Huiting

On Nov 20, 2010, at 5:27 AM, Jan Hudec wrote:

> On Fri, Nov 19, 2010 at 23:15:51 +0800, Dowlin Yang wrote:
>> I sent an email earlier but it seems rejected. I resent again with plain
>> text format. I am sorry for any inconvenience if you receive my messages
>> twice, and please read the new one.
> 
> If it was HTML it was rejected by the list software and nobody ever saw it.
> HTML is not accepted by any of the lists on vger.kernel.org.
> 
>> Suppose A had a branch b1 and B had a branch b2. They work on their own
>> branch separately but b1 and b2 share the same file f1. Suppose A made
>> a few changes to f1 on Nov 5th.
> 
> Dates are irrelevant. What is the most recent common ancestor?
> 
> Note, that most recent common ancestor is such commit, that is reachable from
> both branches ("common ancestor") and it is not reachable from any other
> common ancestor ("most recent"). No mention of dates anywhere -- just
> parent-child relation between commits.
> 
>> Here are A's changes:
>> [snip]
>> A removed one line and added a few lines to f1 and then committed on Nov
>> 5th.
>> 
>> On the other hand, B made a few changes to f1 too on the next day Nov 6th.
>> Here are B's changes:
>> [snip] 
>> B removed a few lines and then committed on Nov 6th.
>> 
>> They kept updating other files in the following days. After a few days, we
>> decide to merge A's branch b1 with B's branch b2. So A did git pull origin
>> b2 in b1, and the expected resultant file is sth like this:
>> [snip]
> 
> Now git -- and for that matter any other version control system out there
> that ever had a merge command -- looks for the most recent common ancestor.
> Let's call it 'a'(1).
> 
> Now git applied both changes from a to b1 and changes from a to b2. It uses
> the 3-way merge algorithm, which is basically:
> - match up all lines that are the same in all three versions
> - for lines where a and b1 is the same, take b2
> - for lines where a and b2 is the same, take b1
> - for lines where b1 and b2 are the same, take b1 (== b2)
> - for lines where a, b1 and b2 all differ, declare conflict
> 
> You can equally think about this algorithm as applying diff from a to b1 to
> b2 or applying diff from a to b2 to b1. All should give the same results(2).
> 
> For adding/removing files, just think of the tree as file listing what files
> are included (where order is ignored, so the same name is always matched up).
> 
> The individual changes are not considered, ever. Only the sum of changes
> since most recent common ancestor on one and the other side.
> 
>> Aren't newer changes supposed to be applied? Why older changes are the
>> final results?
> 
> No. All changes since branch point or last merge are applied.
> 
>> B's b2 branch had com/category_bar.js added earlier than A's b1. A manually
>> added the same changes to b1 on Nov 5th, but later B decided to remove
>> com/category_bar.js from b2 on Nov 6h as I described.
> 
> b2 had category_bar.js added and removed again, so in the end it had no
> changes in category_bar.js
> 
> b1 had category_bar.js added
> 
> No change (between a and b2) versus addition (between a and b1) is addition.
> So category_bar.js is added in the result.
> 
> If you didn't add category_bar.js independently on b1, but instead pulled
> from b2, the pulled revision would have been most recent common ancestor, so
> b1 would see no further change and b2 would see deletion and result would be
> deletion.
> 
> Footnotes:
> ~~~~~~~~~~
> 1) You can query most recent common ancestor with 'git merge-base b1 b2'.
>   You can view/list all commits from common ancestor to b2 with 'b1..b2'
>   refspec to gitk/git log. You can view/list all commits from common
>   ancestor to both b1 and b2 with 'b1...b2' refspec to gitk/git log. You can
>   get the cumulative diff from common ancestor to b2 with 'git diff
>   b1...b2'.
> 
> 2) Unless there are conflicts or a repeated text, in which case patch
>   application (with limited context) would not have enough information on
>   where to apply while 3-way merge would.
> 
> -- 
> 						 Jan 'Bulb' Hudec <bulb@ucw.cz>

      reply	other threads:[~2010-11-20  1:19 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-19 15:15 how git pull works? Dowlin Yang
2010-11-19 15:27 ` Dowlin Yang
2010-11-19 21:27 ` Jan Hudec
2010-11-20  1:18   ` Dowlin Yang [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=BBB0EEDC-25DC-4DB6-8923-762986FC07B0@gmail.com \
    --to=dowlin0820@gmail.com \
    --cc=bulb@ucw.cz \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).