1

On a scale of 1-10, my git skills are -5 for anything beyond pull, commit, push.

I was doing a git rebase on my branch to squash my merges together, using git rebase --interactive [my first commit hash] But as we all know, this will open the editor with all the commits after my first commit.

I wanted to squash my second commit into my first commit, so I smartly decided "Hey, let me use the same command but with the first commit hash I see before my first commit's hash." And so I did.

Diagram for reference

 master ------- commitX --- my branch --- commit1 --- commit2 --- ... --- commitINF.
 |__________another branch____commitA

I wanted commit2 squash into commit1. To do so, I experimented with running git rebase --interactive commitX then I squash commit2 into commit1, and ran git push --force-with-lease

Afterwards, I looked at my branch, and commit2 was squashed into commit1 alright. But now my branch also shows commitX from another branch in my branch's work history, with all of its changes.

What did I do wrong in this case? How should I go about squashing the first two commits in a branch next time?

More importantly, how do I remove commitX from my branch's history WITHOUT removing it from the repo's work history, so that it still shows up in its branch where it belongs?

AMR
  • 146
  • 2
  • 10

2 Answers2

2

Your diagram is not very good, but I think what you meant to draw was this:

V -- W -- commitX (master)
     |       |
     |     commit1 -- commit2 -- commitN (mybranch)
     |
   commitA (anotherbranch)

It is correct to say that if you wish to squash commit2 and commit1 together, you must ask for an interactive rebase that starts as commitX. This will create a TODO list starting at commit1, which you need in order to perform the interactive rebase.

The rest of your question is incoherent given the diagram I have posited. It's possible that I have not guessed quite correctly what you intended to portray.

But your use of phrases like "my branch also shows..." seems to imply that you think a "branch" is this long thin thing consisting of many commits. It isn't. A "branch" in Git is one commit, and that's all it is. The "history" is simply what you get when you start walking backwards from each commit to its parent.

And that walk never stops — until you get to the first commit ever made. In my diagram, for instance, it is correct to say that commitX is part of the history of mybranch — and so is W, and so is V. If you can reach a commit by walking backwards, it's part of the history.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Yes you're right, that's the diagram I had in mind. I think I understand what you mean regarding a branch, but there's a miscommunication on my part regarding what happened. The rebase from commitX successfully squashed commit2 into commit1. But in my case, it also happened to then rebase mybranch's head on top of commitA. So now my commit history on a gui (in this case, bitbucket) shows commitA *and then* commit1, and my branch's parent is now anotherbranch. I'm not sure why that happened at all, hence my question. – AMR May 03 '22 at 18:04
  • Selecting your answer because it ultimately helped me get a better understanding and trace the history back and fix it. Thanks! – AMR May 03 '22 at 18:34
0

In my case, it turned out the reason this happened was human error, as it always is. I pulled the commit from which I ran my rebase, commitA, from the repo's commit log, not keeping in mind that the commit log shows all commits on all branches.

So really, I wasn't rebasing on top of commitX as I thought, I was rebasing on top of commitA.

While it ultimately did squash my commits 1 and 2 together like I wanted, it also rebased my branch on top of anotherbranch, hence me seeing commitA in mybranch's history.


The solution was to simply run another interactive rebase on mybranch, but this time I had to make sure I was running it on the commitSha of the last commit ON MASTER (in this example, commitX).

AMR
  • 146
  • 2
  • 10
  • 1
    It might be useful to you to know that things you do in Git are nearly always trivially undoable. See for example my https://stackoverflow.com/a/71750947/341994 on recovery from an incorrect interactive rebase. – matt May 03 '22 at 19:23
  • 1
    Another problem is that you might not understand how to see a nice graph of the situation? The usual incantation is `git log --graph --oneline --decorate` – matt May 03 '22 at 19:24
  • 1
    Finally, it might help you to read my https://www.biteinteractive.com/picturing-git-conceptions-and-misconceptions/ – matt May 03 '22 at 19:25