Search code examples
gitpowershellversion-controlgit-rebase

Result of git rebase is different from what is shown in the git documentation


Suppose I create a simple local repo following the example shown in the main docs for git rebase:

          A---B---C topic
         /
    D---E---F---G master

I'm on windows so I use Powershell to do this, included for convenience:

md first-example
cd first-example
git init

function Create-Commits
{
    param (
        $Commits,
        $Branch
    )

    foreach ($commit in $commits)
    {
        git checkout $Branch
        new-item "$commit.txt"
        git add "$commit.txt"
        git commit -m "$commit"
        git tag $commit
    }
}

Create-Commits -Commits @("D", "E") -Branch master

git branch topic

Create-Commits -Commits @("A") -Branch topic
Create-Commits @("F") -Branch master
Create-Commits -Commits @("B") -Branch topic
Create-Commits -Commits @("G") -Branch master
Create-Commits -Commits @("C") -Branch topic

git log --graph --format="%(describe:tags=true)" --all
cd ../

Now, according to the text in the docs:

Assume the following history exists and the current branch is "topic":

          A---B---C topic
        /
   D---E---F---G master

From this point, the result of either of the following commands:

git rebase master

git rebase master topic

would be:

                 A'--B'--C' topic
                /
   D---E---F---G master

When I try this, Here's what I get for git log --graph --format="%(describe:tags=true)" --all:

* G-3-g57a4992
* G-2-gcb715a5
* G-1-g5334a53
* G
* F
| * C
| * B
| * A
|/  
* E
* D

Here's what I get for git log --graph --format="%(describe:tags=true)" topic

* G-3-g57a4992
* G-2-gcb715a5
* G-1-g5334a53
* G
* F
* E
* D

And here's what I get for git log --graph --format="%(describe:tags=true)" master

* G
* F
* E
* D

Aside from the fact that the resulting revision history is different from what is stated in the docs, the commits with tags A, B and C don't seem to belong to any branch.

What happened with those commits and why have they not been removed altogether as suggested by the documentation? Do they belong to any specific branch now?


Solution

  • The history still matches, the Git documentation only draws them on 2 parallel lines, your history shows them as a single line.

    A-B-C-D
    

    and

    A-B
       \
        C-D
    

    is exactly the same history.

    As to why you still see your old commits: git rebase never removes commits, it only recreates/copies them and then sets the "branch" label to point to the new commits. The old commits are still in the Git object database (the .git/objects directory).

    git log starts at refs (branches or tags) and will display all commits reachable through those refs; starting at the commit pointed to by the ref, then walking the parent: pointers of each commit.

    You are running git tag $commit for every commit, so they remain reachable, even after creating copies of them and moving the original branch pointer.