6 ms·
This was the most useful piece of information that I have ever read about Git. But what happens if you merge branch A into beanch B? A and B will both contain
by jansan 3y ago
This was the most useful piece of information that I have ever read about Git.
But what happens if you merge branch A into beanch B? A and B will both contain the commits of A, but in B there may be commits of B between the commits that were merged. Do the same commits of A then have different parents depending on which branch they are on?
- paulddraper 3y agoMerging branch A into branch B does two things: 1. Create a new merge commit with two parents: the commit pointed to by A and the commit pointed to by B. 2. Set branch B to point at the new merge commit. This is a non-linear history; when comparing some commits there isn't a "before" or "after."
- hackernews1134 3y agoIf I checkout the merge commit and then do a ‘git log -n 5’, which parent pointer is followed to show the previous commit logs? A or B or Both / all if it is more than a 2-way merge?
- baronswindle 3y agoAs I recall, it shows commits from both parents in order of the committed date.
- paulddraper 3y agoBy default it's by commit date. Other ordering is possible, e.g. --topo-order
- emilecantin 3y agoTo complete the answer, the only difference if you merge branch B into branch A is that A is advanced to the new commit instead.
- seba_dos1 3y ago> Do the same commits of A then have different parents depending on which branch they are on? Absolutely not. Commits are immutable (representing whole repo state, not a diff), and branches are just (mutable) pointers to them. As the sibling already noted, a merge commit is just a regular commit. It simply points to multiple parents, "merging" them. Aside of the whole machinery to resolve conflicts etc. that's pretty much all there is to it. When your graph topology allows it, you can also merge branches without generating a new commit (so called "fast forward" merges) - such a merge does nothing but rewrites the branch pointer. You can also create merge commits that point to more parents than two ("octopus" merges). Reconciling the commits' content can get quite complicated in such cases, but from the repo graph perspective it's nothing special.
- xorcist 3y ago> Commits are immutable (representing whole repo state, not a diff) To make things more clear: Repo state here is the contents of all files, and some metadata including a pointer to the previous commit. So a commit hash uniquely identifies not only a set of files but the unique history leading up to it! That's why we some people like to call git the original block chain (there's no proof of work involved of course so it can never be used for payments or anything like that, but the merkle tree bit is similar enough).
- deleted 3y ago[deleted]
- tharkun__ 3y agoI keep repeating this every time someone talks about git and finds something weird or doesn't get branches, so I'm really glad your parent mentioned it as well and I know there's someone else out there that "gets" that: In git it's all just labels/pointers It's not useful at all to think about branches as the user sees them as "things" of their own. Branches don't "have" anything. Branches in that sense are just convenient labels. Of course actual "branches" in the commit tree exist whether you label them or not. Until `git` does a garbage collection and gets rid of anything that doesn't have a pointer ultimately leading to it - something that a human would understand aka branch/tag. And that's why we call these labels "branches" as well but it's actually one word for two things here. The actual tree branch and the label that's called branch. And a branch and a tag are basically the same exact thing underneath, just a file in the `.git` directory somewhere that contains a commit hash. All the meaning and differentiation of branch or tag is just in the human brain and how we and our tools treat them. Such as if you look at a particular commit in your tool of choice, it will tell you which branch it's part of. To create a branch you can literally just create a thousand randomly named files in the right part of the `.git` directory containing the same commit hash and suddenly this commit "is on all those branches". That's what git does and why creating a branch in git is so super fast.
- seba_dos1 3y agoTo make things more complicated, the word "tag" is also overloaded. It can either be just a reference (in git lingo, a "ref") to a commit - just like a branch, only differing from it in how the tools treat it; but they can also be "annotated tags" which are pointing to a special tag object which contains some metadata and only then points to a specific commit (or other kind of object...) :)
- evntdrvn 3y agoYou’ll also see the first type referred to as “lightweight tags”, if that helps anyone :)
- paulddraper 3y agoYeah they should have called them tags and annotations. Or labels and annotations. Or something else.
- loeg 3y agoIn short: merge commits have multiple parent commits. So your tree tracing logic bifurcates at that point. The commits in the merged history are not altered by the merge commit; they each have a single parent commit (unless they are also merge commits).