1

I have been pushing from 2 different computers to the same main, and somehow I have ended up with different unnamed branches now (those branches below is not something I have actively created on purpose). And neither have I actively done these "Merge branch 'main' of..". The tree looks like this now:

* ee3f.. (HEAD, main) Test Commit
*   9b42.. Merge branch 'main' of..
|\
| *   6640.. Merge branch 'main' of..
| |\
| | *   2c7b.. Merge branch 'main' of..
| | |\
| | | * 4a01.. Updated GUI 1
| | | * 70b5.. Updated GUI 2
| | | * ead5.. Updated GUI 3
| | * | 2005.. Updated GUI 4
| | |/
| | * 63f9 Added error handling

Now I have 3 questions:

  1. What cause these unnamed branches to appear? Referring to the situation where I work against the main branch all the time and push/pull from 2 different computers.

  2. And how come they are automatically merged later

  3. How can I only squash/rebase Updated GUI 1-4 but nothing else? Those branches doesn't have a name since I have chosen anything, but I would like to condensate these 4 commits into one, but I cannot figure it out.

1 Answers1

0
  1. What cause these unnamed branches to appear? Referring to the situation where I work against the main branch all the time and push/pull from 2 different computers.

Answer 1: They're not unnamed. They're all named main. Have you ever been to a party where the host is named Bruce, and all the guests are also named Bruce (and they're not all the same person)?

Answer 2: Git doesn't have branches. Git has, instead, something else called branches.

These two answers aren't wrong, but they aren't right either. They're a victim of Git terminology. The most accurate answer is perhaps the least satisfying: Git has two or three or more things called branches. See What exactly do we mean by "branch"?

  1. And how come they are automatically merged later

You ran git merge, probably via git pull (in fact the message, even edited, virtually guarantees that it was via git pull). Remember, git pull means (1) run git fetch, then (2) based on the result from step 1, run another Git command.

  1. How can I only squash/rebase Updated GUI 1-4 but nothing else?

This is ... difficult, at the least. In particular, updates 1, 2, and 3 are all neatly linear, but update 4 is on a separate branch, in one of the far too many meanings of the word branch, as you can see from this part:

| | | * 4a01.. Updated GUI 1
| | | * 70b5.. Updated GUI 2
| | | * ead5.. Updated GUI 3
| | * | 2005.. Updated GUI 4

Note how the three * items marking the positions of those three commits in the commit graph neatly stack atop each other, but the fourth one is on a separate "line".

You can effectively produce a single commit that contains the same snapshot as this merge result:

| | *   2c7b.. Merge branch 'main' of..

But if and when you do this, these three commits:

* ee3f.. (HEAD, main) Test Commit
*   9b42.. Merge branch 'main' of..
|\
| *   6640.. Merge branch 'main' of..

would then need to be discarded in favor of new and improved commits that merge the one new commit you'd make. That may prove too disruptive to others, depending on who else may be using the other Git repositories involved here.

The quick way to do the combining would be to check out commit:

| | * 63f9 Added error handling

(on a newly-created branch name, to keep track of things, e.g.:

git switch -c newbr 63f9

though there's a good chance you need more than just 4 characters of hash ID here), then use git read-tree -u to replace the current index and working tree from the merge 2c7b:

git read-tree -u 2c7b

(again there's a good chance you need more than just the 4 characters here) and commit. That gives you a new ordinary commit whose parent is 63f9 and whose snapshot is from 2c7b, so that:

git diff newbr 2c7b

should be empty for instance.

You then have to throw out all the subsequent commits and rebuild them, and get everyone else to do the same, and that's the hard part if there is an "everybody else".

torek
  • 448,244
  • 59
  • 642
  • 775