0

If I compare the git/refs when creating a new branch from last commit of a branch versus creating from a detached head state, the git/refs shows different behavior (names) and I like to understand why.

Lets assume the head is on master.

enter image description here

I need a new dev branch. After that, I made some commits to the new branch and some fixes on master.

enter image description here

Now I see another way how to solve the dev branch and I made a second new branch and some commits on that and on master again some fixes.

enter image description here

But now the refs look different! As long as I don't merge plus delete or only delete the second branch still the first two refs called after that second branch.

Why is this a good behavior, cause I cannot easily see that the first refs usually belong to master? Only hashes and parent hashes help with identification, but are a slow method. THX.

EDIT: The information shown here is provided from git log command.

onemorequestion
  • 1,056
  • 1
  • 10
  • 15
  • 1
    So, the issue you are experience is not a Git problem, but rather how you interpret the information given by some tool (`git log` I suspect?). – 0andriy Jul 12 '20 at 15:19
  • Your are right, the information is presented by `git log` but isn't it delivered by git, right? – onemorequestion Jul 12 '20 at 15:53
  • what options do you pass to `git log` ? – LeGEC Jul 12 '20 at 19:31
  • 1
    `git` does not store the information "this commit was first committed on branch xyz". If you ask for something like "name a ref that contains this commit", git may return any such ref – LeGEC Jul 12 '20 at 19:34
  • The relevant options here are `--all --graph` and in `--pretty=format:` we have the commit placeholders p, h, D, S and s. – onemorequestion Jul 13 '20 at 06:57
  • "`git` does not store the information "this commit was first committed on branch xyz"": I see this a little different, but may be wrong. Under `.git/logs/refs/heads/` for every branch the commits are logged with timestamps. In my example you can clearly say where it happens first. – onemorequestion Jul 13 '20 at 07:14
  • Both logs-files of the two branches show that they derive from `052b272`. But strangely only the second one has an impact how `git log` show me the refs for the first two commits. That's what I need to understand ;) and as @0andriy mentioned may only be a problem of `git log`. – onemorequestion Jul 13 '20 at 07:25

1 Answers1

0

Unlike other version control systems you may be familiar with, commits don't belong to any branch. Instead, a branch is just a label that points to a commit. There's no definitive answer to the question "which branch does a commit belong to" or "which branch was a commit written on". Instead, you can only say what commits are reachable by a branch. And that's just what %S does. It works just like --source.

   --source
       Print out the ref name given on the command line by which each commit was
       reached.

In your instance, the first two commits 052b272 and adbf0ae can be reached by several branches. In your first example, by master. In your second by master and B-1. And in your third, by master, B-1, and B-2.

git log --all works by walking the commit graph starting from each reference. If it can reach a commit by multiple refs, it picks whichever ref it happened to be starting from when it prints the log line. Your second log could have easily said they came from B-1 or master. If you make another commit, it may change.

If you run git log without --all, it will say HEAD for all the commits because without --all it works backwards only from HEAD, the current commit.

Schwern
  • 153,029
  • 25
  • 195
  • 336
  • "git log --all works by walking the commit graph starting from each reference..." This is the most interesting part of your answer for me. Exactly this selection process I like to understand. Okay, maybe you have said it all, but only deleting the branch B-2 leads to another pick or another new branch from detached head state. – onemorequestion Jul 13 '20 at 09:36
  • Now I understand that a branch points to a commit and from that I can go backward (maybe more important than the interesting part above ;)) and therefore any ref is a valid result (credits also go to @LeGEC). – onemorequestion Jul 13 '20 at 10:38
  • @onemorequestion I'm not 100% sure, but I assume `git log` acts [deterministically](https://en.wikipedia.org/wiki/Deterministic_algorithm). Given the same history it will produce the same result. It's not picking a branch at random each time. Adding a commit or deleting a branch would can the result. One could dig into `git-log` and figure out exactly what their algorithm is, but there's no guarantee it won't change in the next version. – Schwern Jul 14 '20 at 18:24