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>
prev parent 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).