Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 982
lads Avatar asked Apr 01 '16 08:04

lads


2 Answers

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.

like image 113
poke Avatar answered Oct 21 '22 16:10

poke


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.

like image 34
Enrico Campidoglio Avatar answered Oct 21 '22 17:10

Enrico Campidoglio