Git Tools Rewriting History All In One
Git Tools Rewriting History All In One
Git 工具重写历史
Changing the Last Commit
$ git commit --amend
$ git commit --amend --no-edit
Changing Multiple Commit Messages
git rebase -i
交互式变基 ✅
i => interactive
$ git rebase -h
usage: git rebase [-i] [options] [--exec <cmd>] [--onto <newbase> | --keep-base] [<upstream> [<branch>]]
or: git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] --root [<branch>]
or: git rebase --continue | --abort | --skip | --edit-todo
--onto <revision> rebase onto given branch instead of upstream
--keep-base use the merge-base of upstream and branch as the current base
--no-verify allow pre-rebase hook to run
-q, --quiet be quiet. implies --no-stat
-v, --verbose display a diffstat of what changed upstream
-n, --no-stat do not show diffstat of what changed upstream
--signoff add a Signed-off-by trailer to each commit
--committer-date-is-author-date
make committer date match author date
--reset-author-date ignore author date and use current date
-C <n> passed to 'git apply'
--ignore-whitespace ignore changes in whitespace
--whitespace <action>
passed to 'git apply'
-f, --force-rebase cherry-pick all commits, even if unchanged
--no-ff cherry-pick all commits, even if unchanged
--continue continue
--skip skip current patch and continue
--abort abort and check out the original branch
--quit abort but keep HEAD where it is
--edit-todo edit the todo list during an interactive rebase
--show-current-patch show the patch file being applied or merged
--apply use apply strategies to rebase
-m, --merge use merging strategies to rebase
-i, --interactive let the user edit the list of commits to rebase
--rerere-autoupdate update the index with reused conflict resolution if possible
--empty <{drop,keep,ask}>
how to handle commits that become empty
--autosquash move commits that begin with squash!/fixup! under -i
-S, --gpg-sign[=<key-id>]
GPG-sign commits
--autostash automatically stash/stash pop before and after
-x, --exec <exec> add exec lines after each commit of the editable list
-r, --rebase-merges[=<mode>]
try to rebase merges instead of skipping them
--fork-point use 'merge-base --fork-point' to refine upstream
-s, --strategy <strategy>
use the given merge strategy
-X, --strategy-option <option>
pass the argument through to the merge strategy
--root rebase all reachable commits up to the root(s)
--reschedule-failed-exec
automatically re-schedule any `exec` that fails
--reapply-cherry-picks
apply all changes, even those already present upstream
➜ git git:(test)
$ git rebase -i HEAD~3
# 等价于
# $ git rebase -i HEAD^2
# 修改 commit
$ git commit --amend
$ git rebase --continue
pick f7f3f6d test commit 1
pick 310154e test commit 2
pick a5f4a0d test commit 3
# Rebase 710f0f8..a5f4a0d onto 710f0f8
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
- pick f7f3f6d test commit 1
- pick 310154e test commit 2
- pick a5f4a0d test commit 3
# 三个 commits 合并成一个 commit, 并且修改 commit message ✅
+ pick f7f3f6d test commit 1 & test commit 2 & test commit 3
+ s 310154e test commit 2
+ s a5f4a0d test commit 3
# new commit message 编辑
test commit 1 + test commit 2 + test commit 3
$ git push -f
Reordering Commits
Squashing Commits
Splitting a Commit
Deleting a commit
demo
https://github.com/xgqfrms/frontend-iterview-quetions-collection/issues/1#issuecomment-1212401242
$ git rebase -i HEAD~3
# 等价于
# $ git rebase -i HEAD^2
# 修改 commit
$ git commit --amend
$ git push -f
验证成功 ✅
https://github.com/xgqfrms/frontend-iterview-quetions-collection/commits/main
ccf9cf
e6d899
The Nuclear Option: filter-branch
Removing a File from Every Commit
$ git filter-branch --tree-filter 'rm -f passwords.txt' HEAD
# git filter-branch --tree-filter 'rm -f *~' HEAD
Making a Subdirectory the New Root
$ git filter-branch --subdirectory-filter trunk HEAD
Changing Email Addresses Globally
$ git filter-branch --commit-filter '
if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ];
then
GIT_AUTHOR_NAME="Scott Chacon";
GIT_AUTHOR_EMAIL="schacon@example.com";
git commit-tree "$@";
else
git commit-tree "$@";
fi' HEAD
refs
https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History
©xgqfrms 2012-2020
www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!
原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!
本文首发于博客园,作者:xgqfrms,原文链接:https://www.cnblogs.com/xgqfrms/p/16465388.html
未经授权禁止转载,违者必究!