2

Lets suppose I branch of from master (A) and make a commit there (B) and then a commit on master (C) and then merge them (D):

   B
 /   \
A--C--D  master

Now is there something that sets C apart from B (that makes it on the master branch)?

6
  • 6
    Git doesn't really have an equivalent to a trunk from svn. It has first parents. Please be aware that a branch isn't a list of commits, it is a pointer to a single commit. Commented Jul 26, 2024 at 13:32
  • 2
    In this example, both B and C are "on the master branch". A branch is a tree structure with the branch HEAD at the tip. Commented Jul 26, 2024 at 13:32
  • 2
    Directed acyclic graph (DAG), not tree. Commented Jul 26, 2024 at 13:45
  • 1
    The ref log would record that master once referred to C, but never to B. The commits themselves don't retain any knowledge about what branch heads they may have formerly served as. Commented Jul 26, 2024 at 13:47
  • "A branch is a tree structure". No; a branch is a single commit. There is also some metadata associated with a branch, and humans tend to think of a branch as a chain of commits, but it is better to think of a branch as a single commit. Then questions like this become moot. Commented Jul 26, 2024 at 16:30

3 Answers 3

2

There are a lot of ways to answer this question, but perhaps one fairly succinct way is:

Now is there something that sets C apart from B (that makes it on the master branch)?

We can debate the definition of "on the master branch", but generally:

  • From the point of view of a fresh clone, No.
  • From the point of view of an existing repo that had frequently fetched the history of master over time, then Likely Yes, it is possible to know that at one time master pointed to C, but never pointed to B.

Side Note:

Many tools and branching strategies recommend using --no-ff when merging into important shared branches such as master. This enables you to do a "first parent" history: git log --first-parent master. You cannot tell from the graph in your question, but if you generally use a tool with Pull/Merge Requests which force a merge commit and doesn't allow you to flip the parents when merging, the first-parent history should be preserved and then you can see if master ever pointed to a specific commit.

Sign up to request clarification or add additional context in comments.

1 Comment

'Doesn't allow you to flip the parents when merged' - it's worth mentioning that 'flipping parents' is sometimes called a 'foxtrot merge' (at least making it easier to google) - atlassian.com/blog/developer/stop-foxtrots-now
1

In Git, commits are organized in a data structure called DAG (Directed Acyclic Graph), where each commit only points to their parent(s) (that's why directed), and where there is no route that starting from a commit leads back to the same initial commit (that's why acyclic).

Branches in Git are just implemented as a file with the SHA1 (the ID) of the head commit (the tip) of a branch. They're merely pointers. If you go under .git\refs\heads and open any branch file with a text editor, you would see the SHA1 of the commit they point to.

The heavy lifting that holds together the entire structure (the history of changes) is done by the commits themselves and by how they're organized. Branches do not have any special meaning or functionality. They're just a human-readable and convenient way to refer to the latest changes on a development line.

So, to answer your question

Now is there something that sets C apart from B (that makes it on the master branch)?

Commit objects alone do not have any properties that say whether they are on a branch or another, like a branch pointer. However, their histories (so, sets of commits as a whole) can tell whether they belong, or belonged, to a same line of development or not. Therefore, you could actually tell B and C apart if you ran git log with the --first-parent option.

git log --first-parent

Running this command from the master branch will show you commits D, C, A but not B, as only the formers happened on the history of the first parent (master), while B happened on the history of the other branch.

Comments

1

A branch is a pointer to a commit. If you have a branch checked out, then once you commit your branch will become a pointer to your newest commit that was done while that branch was being checked out. Of course, using git log you can check what commits let to the current one and you can check out those commits via their hashes too.

Your master is on D and it has the changes both from C (earlier commit on master) and B (due to the merge). If you checkout C (earlier commit on master), then D will not be part of it nor the merge.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.