Re: If merging that is really fast forwarding creates new commit [Was: Re: how to show log for only one branch]

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

 



Andy Whitcroft wrote:
Liu Yubao wrote: But in that situation you and Alice now have different actual history
DAG's in your repositories.

Alice sees:
a---b---c---d-----------h
             \         /
              e---f---g

Bob sees:
a---b---c---d-----------h
             \         / \
              e---f---g---i


If bob now adds a new commit 'j' and alice pulls it back we either have
to then accept 'i' at alice's end or forever lose the identicality of
the commit DAG.  At which point our primary benefit of the SHA1 ==
parent == same commit for everyone is gone.  We can no longer say "this
commit is broken" and everyone know which commit that is.

Alice and bob have their own branch scope view respectively, they have two
different branches, their DAGs in *branch scope view* can
be different because they trace the history from different points.

In branch scope view, you see only one HEAD, it merges changes from
other branches. Each branch has its own commit DAG.

In global scope view, you see many HEADs, they fork and merge frequently,
here is only one big commit DAG, but you can never see the whole as branches
can be distributed over the world.

Fake commit doesn't break the DAG in global scope view, it has parents
as normal commit although the trees pointed by fake commit and its parent
are same. In fact, git has suck commit already:

  a (tree_1) -------  b (tree_2)  ---- d (tree_2) ---> master
   \                                    /
    `---------------  c (tree_2) ------' -----> test

If you don't pull from other, you can get different global DAG, it's normal obviously. It doesn't matter you get different DAG in branch scope, of course
they are different.

The problem is you can't get branch *track* from global scope view in git, you
can't tell which commits a branch has *referred to*. Note following HEAD^1 isn't right as Junio pointed out (http://marc.theaimsgroup.com/?l=git&m=116279354214757&w=2).

Branch track is useful as people have requested reflog feature (realized, but
only for local purpose) and "note" extension in commit object.

If you have a commit A that I haven't pulled, I can't know what you
refer to when you say "Commit A introduced a bug". I must know where
to get this commit. After I pull it from other branch, We can say "this
commit is broken" and everyone know which commit that is.

We create a fake commit for fast forwarding style merge, this fake commit
is used to record the track of a branch, so we can always follow HEAD^1
to travel through the history of a branch. In fact, git pays more attention
to the history of *data modification* than history of *operation*, that is
right the subtle difference between content tracker and VCS, latter's
branch has more information(useful information, I think).

Any VCS is concerned with data modification and how its tracked.  There
are two ways you can record history.  A series of snapshots (git) or a
series of operations (eg cvs and svn).  Each has its trade offs,
operations like diff on snapshots is O(number of files), on diffs they
are O(number of files * number of deltas).

The difference here is all about the interpretation of the word
'branch'.  In CVS and others there is the hard concept of a mainline --
here is the master copy when something is added here it is "the one",
branches are temporary places which contain 'different' history such as
a patch branch.  You want something on both branches you commit the
change twice once to each.  In git they are more separate future
histories.  When they are merged back together the new single history
contains the changes in both, neither is more important than the other
both represent forward progress.  People tend to draw as below giving a
false importance to the 'line' from d->h:

a---b---c---d-----------h
             \         /
              e---f---g

We probabally should draw the below, h's history contains all history
from both 'up' and 'down' histories.  Which is more important?  Neither.
 h is made up of a,b,c,d from alice and e,f,g from bob merged by alice.

              ---------
             /         \
a---b---c---d           h
             \         /
              e---f---g


If fake commit is introduced, a possible revision graph is like this:

  a - * -- c  ------- * ---> branchA
   \ /      \         /
    b ------ * ---- d ---> branchB      ('*' stands for fake commit)

It's indeed not pretty as a linear revision graph that git's fast forwarding
style merge creates, but it can record the tracks of two branches by following
HEAD^1.

-
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]