git commad —— git reset —— 修改branch的commit

# checkout 远程分支hotfix/v3.3.1_20378_website

$ git reset --hard f93b9e23dee9ff0a81ece8a45d572a000d6c86a8

# 强制远程分支推送。否则如果 commit较新,则会自动 提示需要提交commit
$ git push -f origin hotfix/v3.3.1_20378_website


  

如果merge 回滚,

先 git merge --abort(如果已经commit,未push到remote,则 cancle commit first,然后 merge --abort)

或者 git merge revert

 

git reset 是最后的方式,其他方式可以完成的,有限使用其他方式。因为会影响 team中其他人的开发。(通知team其他人,删除本地分支,重新 checkout 远程分支:hotfix/v3.3.1_20378_websit),因其他人 本地的 commit 是旧的,可能commit 比较新,则可能在无意识的情况下,提交 之前 丢弃的 commit

 

$ git status

$ git cherry-pick 038da250553e4f32752a23d56a01cc2696ec1410


$ git push

$ git cherry-pick ac378fcef8345b3241e94e5713755a4a3fedd848

# 循环

# 通知team其他人,删除本地分支,重新 checkout 远程分支:hotfix/v3.3.1_20378_website

  

 

4 Easy Steps to Change Author Name of a Commit After Push

  1. Rebase the repository to the previous commit of the one you want to change by running:
    git rebase –i {{previous-commit-hash}}
  2. The script above prompts you with a list of your commits in descendent order. On this vi/vim view, replace the word pick to edit per each commit you want to edit. Then quit and save.
  3. When the rebase process starts, change the author of a commit by running git commit --amend --author="Author <email@email.com>". Then, continue to next commit using: git rebase –continue
  4. Once the rebase process finishes, push your changes by running: git push -f

The steps above will change the author of a commit. But what is the meaning of each commands above and what it means to change a git repository’s history?

I came across this question recently after changing the settings on GitHub page and seen that commits were logged with invalid an invalid name. Reading through Git’s documentation made it tricky to find the answer. This Stack Overflow answer nail it but I still decided to write about it to review the concepts behind scenes.

What does the rebase commit do?

The rebase command basically integrates changes from one branch into another. It is an alternative to the “merge” command. The difference between rebase and merge is that rebase rewrites the commit history and creates a linear succession of commits, while merging adds a new commit to the destination branch. The image bellow perfectly shows a visual representation of both processes.

Git amend command

The amend command allows git users to change details of a commit. The amend structure is simple:
git commit –amend

This will prompt a vi/vim view where the details of a git commit can be changed:

update changelog file
# Please enter the commit message for your changes. Lines starting
# with ‘#’ will be ignored, and an empty message aborts the commit.
#
# Author: Author Name < name@email.com >
# Date: Thu Jan 10 22:40:30 2020 -0300
#
# On branch some_branch
# Your branch is up-to-date with ‘origin/some_branch’.
#
# Changes to be committed:
# modified: changelog.md

It is possible to change the author of a git commit directly as seen before:
git commit --amend --author="Author < email@email.com > "

Change git history… Caution!

Those who are familiar with rebasing know how powerful the tool it is. It might be tempting to use it all the time as well.

When getting conflicts during a rebase, Git pauses on the conflicting commit and allows to fix conflict before proceeding. However, solving conflicts in the middle of a long chain of commits is often confusing and another source of potential errors.

Rebasing creates this linear mind-set and give less priority to the actual goal of git. That is why it is not recommended to change the history of a git repository unless there is no alternative to it.

In my case, I was the only user interacting with the repository so it was safe. However, when multiple developers are working on multiple branches, change to the git history can become a real source of problems.

References

 

 

How to change the commit author for one specific commit?

 
 

Interactive rebase off of a point earlier in the history than the commit you need to modify (git rebase -i <earliercommit>). In the list of commits being rebased, change the text from pick to edit next to the hash of the one you want to modify. Then when git prompts you to change the commit, use this:

git commit --amend --author="Author Name <email@address.com>" --no-edit

For example, if your commit history is A-B-C-D-E-F with F as HEAD, and you want to change the author of C and D, then you would...

  1. Specify git rebase -i B (here is an example of what you will see after executing the git rebase -i B command)
    • if you need to edit A, use git rebase -i --root
  2. Change the lines for both C and D from pick to edit
  3. Exit the editor (for vim, this would be pressing Esc and then typing :wq).
  4. Once the rebase started, it would first pause at C
  5. You would git commit --amend --author="Author Name <email@address.com>"
  6. Then git rebase --continue
  7. It would pause again at D
  8. Then you would git commit --amend --author="Author Name <email@address.com>" again
  9. git rebase --continue
  10. The rebase would complete.
  11. Use git push -f to update your origin with the updated commits.

 

if you don't know what editor you're in, the answer is likely vim. To save and quit, type Esc : w q Enter. On the other hand, if it's Nano and you see things like "WriteOut: ^O" along the bottom, then you should use Ctrl+O, Enter, Ctrl+X instead

note that you can set the commit author to the current user with git commit --amend --reset-author

Use --no-edit option. git commit --amend --reset-author --no-edit won't open an editor. Available since git 1.7.9.

 to modify the very first commit in the project, use git rebase -i --root

 

 

622

The accepted answer to this question is a wonderfully clever use of interactive rebase, but it unfortunately exhibits conflicts if the commit we are trying to change the author of used to be on a branch which was subsequently merged in. More generally, it does not work when handling messy histories.

Since I am apprehensive about running scripts which depend on setting and unsetting environment variables to rewrite git history, I am writing a new answer based on this post which is similar to this answer but is more complete.

The following is tested and working, unlike the linked answer. Assume for clarity of exposition that 03f482d6 is the commit whose author we are trying to replace, and 42627abe is the commit with the new author.

  1. Checkout the commit we are trying to modify.

     git checkout 03f482d6
    
  2. Make the author change.

     git commit --amend --author "New Author Name <New Author Email>"
    

Now we have a new commit with hash assumed to be 42627abe.

  1. Checkout the original branch.

  2. Replace the old commit with the new one locally.

     git replace 03f482d6 42627abe
    
  3. Rewrite all future commits based on the replacement.

     git filter-branch -- --all
    
  4. Remove the replacement for cleanliness.

     git replace -d 03f482d6
    
  5. Push the new history (only use --force if the below fails, and only after sanity checking with git log and/or git diff).

     git push --force-with-lease
    

Instead of 4-5 you can just rebase onto new commit:

git rebase -i 42627abe




If the commit that you want to change is not the last commit, then follow the below steps. If your commit is in different branch then first switch to that branch.

git checkout branch_name

Find commit before the commit that you want to change and find its hash. Then issue rebase command.

git rebase -i -p hash of commit

Then an editor will open and enter 'edit' for the commits that you want to change. Leave others with default 'pick' option. Once changed enter 'esc' key and wq! to exit.

Then issue git commit command with amendment option.

git commit --amend --author="Username email" --no-edit

Then issue the following command.

git rebase --continue

Once commit author is updated in the local repository, push the changes to the remote repository.

 

 

 

Steps to rename author name after commit pushed

  1. First type "git log" to get the commit id and more details
  2. git rebase i HEAD~10 (10 is the total commit to display on rebase)

    If you Get anything like below

    fatal: It seems that there is already a rebase-merge directory, and I wonder if you are in the middle of another rebase. If that is the case, please try

    git rebase (--continue | --abort | --skip) If that is not the case, please rm -fr ".git/rebase-merge" and run me again. I am stopping in case you still have something valuable there.

  3. Then type "git rebase --continue" or "git rebase --abort" as per your need

    • now your will rebase window opened, click "i" key from keyboard
    • then you will get list of commits to 10 [because we have passed 10 commit above] Like below

    pick 897fe9e simplify code a little

    pick abb60f9 add new feature

    pick dc18f70 bugfix

  4. Now you need to add below command just below of the commit you want to edit, like below

    pick 897fe9e simplify code a little exec git commit --amend --author 'Author Name <author.name@mail.com>' pick abb60f9 add new feature exec git commit --amend --author 'Author Name <author.name@mail.com>' pick dc18f70 bugfix exec git commit --amend --author 'Author Name <author.name@mail.com>'

    1. That's it, now just press ESC, :wq and you are all set

    2. Then git push origin HEAD:BRANCH NAME -f [please take care of -f Force push]

    like git push -f or git push origin HEAD: dev -f

 

  1. Change commit author name & email by Amend, then replacing old-commit with new-one:

    $ git checkout <commit-hash>                            # checkout to the commit need to modify  
    $ git commit --amend --author "name <author@email.com>" # change the author name and email
    
    $ git replace <old-commit-hash> <new-commit-hash>      # replace the old commit by new one
    $ git filter-branch -- --all                           # rewrite all futures commits based on the replacement                   
    
    $ git replace -d <old-commit-hash>     # remove the replacement for cleanliness 
    $ git push -f origin HEAD              # force push 
    
  2. Another way Rebasing:

    $ git rebase -i <good-commit-hash>      # back to last good commit
    
    # Editor would open, replace 'pick' with 'edit' before the commit want to change author
    
    $ git commit --amend --author="author name <author@email.com>"  # change the author name & email
    
    # Save changes and exit the editor
    
    $ git rebase --continue                # finish the rebase

 

9

If you are the only user of this repository, you can rewrite history using either git filter-branch (as svick wrote), or git fast-export/git fast-import plus filter script (as described in article referenced in docgnome answer), or interactive rebase. But either of those would change revisions from first changed commit onwards; this means trouble for anybody that based his/her changes on your branch pre-rewrite.

RECOVERY

If other developers didn't based their work on pre-rewrite version, simplest solution would be to re-clone (clone again).

Alternatively they can try git rebase --pull, which would fast-forward if there weren't any changes in their repository, or rebase their branch on top of re-written commits (we want to avoid merge, as it would keep pre-rewrite comits forever). All of this assuming that they do not have not comitted work; use git stash to stash away changes otherwise.

If other developers use feature branches, and/or git pull --rebase doesn't work e.g. because upstream is not set up, they have to rebase their work on top of post-rewrite commits. For example just after fetching new changes (git fetch), for a master branch based on / forked from origin/master, one needs to run

$ git rebase --onto origin/master origin/master@{1} master

Here origin/master@{1} is pre-rewrite state (before fetch), see gitrevisions.


Alternate solution would be to use refs/replace/ mechanism, available in Git since version 1.6.5. In this solution you provide replacements for commits that have wrong email; then anybody who fetches 'replace' refs (something like fetch = +refs/replace/*:refs/replace/* refspec in appropriate place in their .git/config) would get replacements transparently, and those who do not fetch those refs would see old commits.

The procedure goes something like this:

  1. Find all commits with wrong email, for example using

    $ git log --author=user@wrong.email --all
    
  2. For each wrong commit, create a replacement commit, and add it to object database

    $ git cat-file -p <ID of wrong commit> | 
      sed -e 's/user@wrong\.email/user@example.com/g' > tmp.txt
    $ git hash-object -t commit -w tmp.txt
    <ID of corrected commit>
    
  3. Now that you have corrected commit in object database, you have to tell git to automatically and transparently replace wrong commit by corrected one using git replace command:

    $ git replace <ID of wrong commit> <ID of corrected commit>
    
  4. Finally, list all replacement to check if this procedure succeded

    $ git replace -l
    

    and check if replacements take place

    $ git log --author=user@wrong.email --all
    

You can of course automate this procedure... well, all except using git replace which doesn't have (yet) batch mode, so you would have to use shell loop for that, or replace "by hand".

NOT TESTED! YMMV.

Note that you might encounter some rough corners when using refs/replace/ mechanism: it is new, and not yet very well tested.

 

 

 

 

 

posted @ 2022-02-15 22:12  PanPan003  阅读(125)  评论(0编辑  收藏  举报