Showing posts with label GIT --amend. Show all posts
Showing posts with label GIT --amend. Show all posts

Friday, 28 December 2018

GIT: How can I change the author name / email of a commit?

Before we jump into solutions, let's find out what exactly it is you want to accomplish:
a) Change the author information before making a commit
b) Change the author information after making a commit (i.e. for historical commits)

Changing Your Git Author Identity

There are three ways to change your committer identity in Git. All of these methods only affect future commits, not past ones!

Changing Your Committer Name & Email Globally

You can run the "git config" command with the --global flag; this will make sure all of your future commits use the given information:
$ git config --global user.name "John Doe"
$ git config --global user.email "john@doe.org"

Changing Your Committer Name & Email per Repository

If you want to use special settings only when working in a certain repository, you can simply omit the --global flag. This makes the configuration valid only in thatrepository:
$ git config user.name "John Doe"
$ git config user.email "john@doe.org"

Changing the Author Information Just for the Next Commit

Finally, with the --author flag, you can also overwrite the author information for just the next commit:
git commit --author="John Doe <john@doe.org>"

Editing the Author of Past Commits

NOTE

Editing Past Commits Rewrites History!

No matter how exactly we change the information of past commits, there's one thing to always keep in mind: if we do this, we are effectively rewriting commit history.
This is nothing to take lightly: you will create new commit objects in this process, which can become a serious problem for your collaborators - because they might have already based new work on some of the original commits.
Therefore, think twice before you rewrite your commit history!
There are three basic ways to edit your past commits:

Using --amend for the Very Last Commit

In case you want to change just the very last commit, Git offers a very easy way to do this:
git commit --amend --author="John Doe <john@doe.org>"
This effectively replaces the last commit with your "edited" version, correcting the wrong author information.

Using Interactive Rebase

Interactive Rebase is the Swiss Army Knife of tools in Git: it allows you to do and change almost anything. However, being as powerful as it is, this also means you can very easily shoot yourself in the foot. Use it with care (and possibly read up on it)!
The first step is to identify the last "good" commit and provide its hash to the rebase command:
$ git rebase -i -p 0ad14fa5
Your editor will open, requesting you to mark all the commits you want to change with the "edit" keyword.

Git will now walk you through each commit, giving you the chance to mold it as you desire:
Stopped at 5772b4bf2... Add images to about page
You can amend the commit now, with

    git commit --amend

Once you are satisfied with your changes, run

    git rebase --continue
Your job, now, is to correct the author information and then continue to the next concerned commit object until you've edited all the commits you just marked:
$ git commit --amend --author="John Doe <john@doe.org>" --no-edit
$ git rebase --continue

Using git filter-branch

Another way is to use Git's "filter-branch" command. It allows you to batch-process a (potentially large) number of commits with a script.
You can run the below sample script in your repository (filling in real values for the old and new email and name):
$ git filter-branch --env-filter '
WRONG_EMAIL="wrong@example.com"
NEW_NAME="New Name Value"
NEW_EMAIL="correct@example.com"

if [ "$GIT_COMMITTER_EMAIL" = "$WRONG_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$NEW_NAME"
    export GIT_COMMITTER_EMAIL="$NEW_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$WRONG_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$NEW_NAME"
    export GIT_AUTHOR_EMAIL="$NEW_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags
The same warning applies to this method as to the others mentioned: you are rewriting history with this command, creating new commit objects along the way!
Preferably, you should only do this in repositories that haven't been published / shared, yet. In any other case you should use it with extreme care - and only if you're aware of the side effects!

Thursday, 27 December 2018

GIT: How can I edit / fix the last commit's message?

Made a typo in your commit message? Or forgot to mention an important detail in the message? Correcting a commit message in Git can be very easy - if it's the very last commit you want to edit!

Amending the Last Commit

To change the last commit, you can simply commit again, using the --amend flag:
$ git commit --amend -m "New and correct message"
Simply put, this overwrites your last commit with a new one. This also means that you're not limited to just editing the commit's message: you could also add another couple of changes you forgot.
$ git add another/changed/file.txt
$ git commit --amend -m "message"
However, keep two important details in mind:
  1. Amend only works with the very last commit. If you notice your mistake only after adding another commit, amend won't help you much.
  2. Amend rewrites the commit history in your repository: the old commit is replaced by a completely new one (a new and different commit object). This makes it very important that you don't amend (= rewrite) commits that you've already publishedto a remote repository! Because in that case, your colleagues might have already based their work on this commit - which you would try to replace using "amend".
Therefore, use "amend" whenever you want to change / edit your very last and unpushed commit.

hanging Older Commits


If you want to change older commits, Git also has a tool for this use case:
$ git rebase --interactive
The "interactive rebase" command, however, is quite an advanced tool: very powerful and quite dangerous. You should definitely understand what you're doing before applying it! See here if you really need to use it.
The mode of action, however, is the same as with the --amend flag: you are rewriting history! Therefore, just as with amend, you should not use interactive rebasing on commits you have already pushed!

GIT: How to change git commit message after push?

If it is the most recent commit, you can simply do this:

git commit --amend
This brings up the editor with the last commit message and lets you edit the message. (You can use -m if you want to wipe out the old message and use a new one.)

And then when you push, do this:

git push --force <repository> <branch>
Be careful when using push --force. If anyone else has pushed changes to the same branch, those changes will be destroyed.

Anyone who already pulled will not get an error message, and they will need to update (assuming they aren't making any changes themselves) by doing something like this:

git fetch origin
git reset --hard origin/master # Loses local commits
Be careful when using reset --hard. If you have changes to the branch, those changes will be destroyed.

A note about modifying historyEdit
The destroyed data is really just the old commit message, but --force doesn't know that, and will happily delete other data too. So think of --force as "I want to destroy data, and I know for sure what data is being destroyed." But when the destroyed data is committed, you can often recover old commits from the reflog—the data is actually orphaned instead of destroyed (although orphaned commits are periodically deleted).

If you don't think you're destroying data, then stay away from --force

GIT: Changing git commit message after push (given that no one pulled from remote)

I have made a git commit and subsequent push. I would like to change the commit message. If I understand correctly, this is not advisable because someone might have pulled from the remote repository before I make such changes. What if I know that no one has pulled?
Is there a way to do this?


Changing history

If it is the most recent commit, you can simply do this:
git commit --amend
This brings up the editor with the last commit message and lets you edit the message. (You can use -m if you want to wipe out the old message and use a new one.)

Pushing

And then when you push, do this:
git push --force-with-lease <repository> <branch>
Or you can use "+":
git push <repository> +<branch>
Or you can use --force:
git push --force <repository> <branch>
Be careful when using these commands.
  • If someone else pushed changes to the same branch, you probably want to avoid destroying those changes. The --force-with-lease option is the safest, because it will abort if there are any upstream changes (
  • If you don't specify the branch explicitly, Git will use the default push settings. If your default push setting is "matching", then you may destroy changes on several branches at the same time.

Pulling / fetching afterwards

Anyone who already pulled will now get an error message, and they will need to update (assuming they aren't making any changes themselves) by doing something like this:
git fetch origin
git reset --hard origin/master # Loses local commits
Be careful when using reset --hard. If you have changes to the branch, those changes will be destroyed.

A note about modifying history

The destroyed data is really just the old commit message, but --force doesn't know that, and will happily delete other data too. So think of --force as "I want to destroy data, and I know for sure what data is being destroyed." But when the destroyed data is committed, you can often recover old commits from the reflog—the data is actually orphaned instead of destroyed (although orphaned commits are periodically deleted).
If you don't think you're destroying data, then stay away from --force... bad things might happen.
This is why --force-with-lease is somewhat safer.