lads
lads

Reputation: 1195

If I push an amended commit will it create a new commit?

I have already pushed a commit on the remote branch and now I want to change its content, so I tried git amend.

If do git status it says that the two branches have 1 and 1 different commits each, respectively.

Now if I push the amended commit with the same commit message, will that add a new commit or it will change the last commit I have pushed?

Upvotes: 9

Views: 6860

Answers (3)

Enrico Campidoglio
Enrico Campidoglio

Reputation: 59923

tl;dr

Pushing an amended commit means pushing a different commit.

Anatomy of a Commit ID

The unique ID of a commit is made up of the SHA-1 hash of its metadata. Which metadata? One of the ways to find out is by using the cat-file plumbing command:

git cat-file -p HEAD

After you run this command you'll see a list containing these fields:

  • Tree
  • Parent
  • Author
  • Committer
  • Message

If any of these fields change, their SHA-1 hash is also going to change granting the commit a whole new ID.

Amending is Rewriting History

That's why if you amend a commit – for example by changing its message – it's going to have a different ID than it had previously. You're effectively rewriting history.

Note that the ID of the commit's parent is also included in the metadata. This means that once a commit changes ID, all of its descendants are also going to change IDs like a domino effect.

Upvotes: 2

poke
poke

Reputation: 387825

git commit --amend, just like git rebase, will create a new commit object. That object is based on a previously existing commit but it is still a new commit and replaces the old one completely.

Looking at the history, this could look like this:

                master
                  ↓
* --- * --- * --- A

Considering that A is the original commit. If we now amend this commit, then we get the following result:

* --- * --- * --- A
              \
               --- A'
                   ↑
                 master

So we get a different commit object A', with a different hash, and the branch we were on (here: master) is updated to point to this one.

Now, if we add a remote repository to that view, and we pushed A previously to the remote, then it looks like this:

             origin/master
                  ↓
* --- * --- * --- A
              \
               --- A'
                   ↑
                 master

So the remote still points at the original commit A, but our local branch points at the modified A'. This is a problem because we cannot push A' and make origin/master point at A' as this would remove the already pushed commit A from the history.

We can perform a forced push using git push --force to force Git to update the remote branch and indeed delete A from the history. It is important to note though that this will break everyone’s history who already fetched A from the remote. If some other developer has A and now the remote points at A', then they have a conflict which they have to fix manually. This is often a pain to do, so there is a rule you should follow at all times:

Never rebase (or amend) previously published commits.

The better alternative is to add a new commit B which simply does the fixes to A:

             origin/master
                  ↓
* --- * --- * --- A --- B
                        ↑
                      master

That way, the already published history is still compatible with the new history, so we can push B to the remote without conflicts, and everyone is happy.

Upvotes: 15

Tim
Tim

Reputation: 9042

Once you have pushed to the remote you should not amend any existing commits locally.

You've essentially created a new commit locally (there is a new commit ID) and replaced the old one but the old one still exists on the remote. This causes the 1 ahead and 1 behind message you see.

To resolve you'll need to create a new branch to keep your amendments, check back out the initial branch, reset back to before you made the amendment, pull down the change from the remote. Then merge in your separate branch and push back up.

Upvotes: 1

Related Questions