修改git最后一次提交的命令
$ git commit --amend
修改git最后一次提交用户名的相关命令
git config user.name 'wangz' git config user.email 'wangz@alib.com' git commit --amend --author=wangz
修改最后一次提交内容的相关文档
$ git commit --amend --help usage: git commit [options] [--] <pathspec>... -q, --quiet suppress summary after successful commit -v, --verbose show diff in commit message template Commit message options -F, --file <file> read message from file --author <author> override author for commit --date <date> override date for commit -m, --message <message> commit message -c, --reedit-message <commit> reuse and edit message from specified commit -C, --reuse-message <commit> reuse message from specified commit --fixup <commit> use autosquash formatted message to fixup specified commit --squash <commit> use autosquash formatted message to squash specified commit --reset-author the commit is authored by me now (used with -C/-c/--amend) -s, --signoff add Signed-off-by: -t, --template <file> use specified template file -e, --edit force edit of commit --cleanup <default> how to strip spaces and #comments from message --status include status in commit message template -S, --gpg-sign[=<key id>] GPG sign commit Commit contents options -a, --all commit all changed files -i, --include add specified files to index for commit --interactive interactively add files -p, --patch interactively add changes -o, --only commit only specified files -n, --no-verify bypass pre-commit hook --dry-run show what would be committed --short show status concisely --branch show branch information --porcelain machine-readable output --long show status in long format (default) -z, --null terminate entries with NUL --amend amend previous commit --no-post-rewrite bypass post-rewrite hook -u, --untracked-files[=<mode>] show untracked files, optional modes: all, normal, no. (Default: all)
$ ssh -v wangz@gitlab.alibaxx-inc.com
$ git remote ali set-url git@gitlab.alibaxx-inc.com:youk-aaa/xxx.git
任何时候,你都有可能需要撤消刚才所做的某些操作。接下来,我们会介绍一些基本的撤消操作相关的命令。请注意,有些撤销操作是不可逆的,所以请务必谨慎小心,一旦失误,就有可能丢失部分工作成果。
有时候我们提交完了才发现漏掉了几个文件没有加,或者提交信息写错了。想要撤消刚才的提交操作,可以使用 --amend
选项重新提交:
$ git commit --amend
此命令将使用当前的暂存区域快照提交。如果刚才提交完没有作任何改动,直接运行此命令的话,相当于有机会重新编辑提交说明,但将要提交的文件快照和之前的一样。
启动文本编辑器后,会看到上次提交时的说明,编辑它确认没问题后保存退出,就会使用新的提交说明覆盖刚才失误的提交。
如果刚才提交时忘了暂存某些修改,可以先补上暂存操作,然后再运行 --amend
提交:
$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend
上面的三条命令最终只是产生一个提交,第二个提交命令修正了第一个的提交内容。
接下来的两个小节将演示如何取消暂存区域中的文件,以及如何取消工作目录中已修改的文件。不用担心,查看文件状态的时候就提示了该如何撤消,所以不需要死记硬背。来看下面的例子,有两个修改过的文件,我们想要分开提交,但不小心用 git add .
全加到了暂存区域。该如何撤消暂存其中的一个文件呢?其实,git status
的命令输出已经告诉了我们该怎么做:
$ git add .
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README.txt
modified: benchmarks.rb
就在 “Changes to be committed” 下面,括号中有提示,可以使用 git reset HEAD <file>...
的方式取消暂存。好吧,我们来试试取消暂存 benchmarks.rb 文件:
$ git reset HEAD benchmarks.rb
Unstaged changes after reset:
M benchmarks.rb
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: benchmarks.rb
这条命令看起来有些古怪,先别管,能用就行。现在 benchmarks.rb 文件又回到了之前已修改未暂存的状态。
如果觉得刚才对 benchmarks.rb 的修改完全没有必要,该如何取消修改,回到之前的状态(也就是修改之前的版本)呢?git status
同样提示了具体的撤消方法,接着上面的例子,现在未暂存区域看起来像这样:
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: benchmarks.rb
在第二个括号中,我们看到了抛弃文件修改的命令(至少在 Git 1.6.1 以及更高版本中会这样提示,如果你还在用老版本,我们强烈建议你升级,以获取最佳的用户体验),让我们试试看:
$ git checkout -- benchmarks.rb
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README.txt
可以看到,该文件已经恢复到修改前的版本。你可能已经意识到了,这条命令有些危险,所有对文件的修改都没有了,因为我们刚刚把之前版本的文件复制过来重写了此文件。所以在用这条命令前,请务必确定真的不再需要保留刚才的修改。如果只是想回退版本,同时保留刚才的修改以便将来继续工作,可以用下章介绍的 stashing 和分支来处理,应该会更好些。
记住,任何已经提交到 Git 的都可以被恢复。即便在已经删除的分支中的提交,或者用 --amend
重新改写的提交,都可以被恢复(关于数据恢复的内容见第九章)。所以,你可能失去的数据,仅限于没有提交过的,对 Git 来说它们就像从未存在过一样。
git reset –hard orgin/master
$ git push bit 1.8-subchannels To git@bitbucket.org:cms.git ! [rejected] 1.8-subchannels -> 1.8-subchannels (fetch first) error: failed to push some refs to 'git@bitbucket.orgcms.git' hint: See the 'Note about fast-forwards' in 'git push --help' for details. $ git pull bit 1.8-subchannels remote: Counting objects: 5, done. remote: Compressing objects: 100% (5/5), done. remote: Total 5 (delta 4), reused 0 (delta 0) Unpacking objects: 100% (5/5), done. From bitbucket.org:cms * branch 1.8-subchannels -> FETCH_HEAD e1faddc..a14be49 1.8-subchannels -> bit/1.8-subchannels Merge made by the 'recursive' strategy. app/controllers/subchannels_controller.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) $ git log commit c9f151b41286ac10656dcb8177abee1 Merge: fee23b3 a14be49 Author: w Date: Tue Apr 12 11:20:31 2016 +0800 Merge branch '1.8-subchannels' of bitbucket.org:cms into 1.8-subchannels commit fee23b36ead5ad8991097204001954b Author: w Date: Tue Apr 12 11:20:03 2016 +0800 add version to 1.2 subchannel commit a14be49f66a5865fc6253d9f4ae655b Author: R Date: Tue Apr 12 10:48:16 2016 +0800 Fix else if syntax error commit e1faddc216081deea2c7e80657369732c Author: w Date: Mon Apr 11 18:30:16 2016 +0800 add version to subchannel $ git reset --hard fee23b36ead5ad899109720400 HEAD is now at fee23b3 add version to 1.2 subchannel $ git pull --rebase bit 1.8-subchannels $ git push bit 1.8-subchannels Counting objects: 68, done. Delta compression using up to 4 threads. Compressing objects: 100% (12/12), done. Writing objects: 100% (12/12), 1.18 KiB | 0 bytes/s, done. Total 12 (delta 8), reused 0 (delta 0) remote: remote: Create pull request for 1.8-subchannels: remote: https://bitbucket.orgcms/pull-requests/new?source=1.8-subchannels&t=1 remote: To git@bitbucket.org:cms.git a14be49..a76e5cb 1.8-subchannels -> 1.8-subchannels
$ git reset --hard bit/add $ git log --oneline --graph 下载远程分支 git fetch -a
249 git reset –hard bit/master
250 git pull
251 git branch –set-upstream-to=bit/master
252 git pull
把一个分支中的修改整合到另一个分支的办法有两种:merge和rebase,
当开发进程分叉到两个不同的分支,又各自提交了更新。
最容易的整合分支的方法是merge, 它会把两个分支最新的快照以及两者的共同祖先进行三方合并,合并的结果是产生一个新的提交对象。
其实还有另外一个选择,可以在一个分支里发生的变化补丁在另一个分支重新打一遍,这种操作叫做衍合,
rebase的作用就是把在一个分支里提交的改变放到另一个分支里重放一遍。
$ git checkout experiment $ git rebase master
它的原理是回到两个分支最近的共同祖先,根据当前分支(也就是要进行衍合的分支experiment)后续的历次提交对象,生成一系列文件补丁,然后以基线分支(也就是主干分支master)最后一个提交对象为新的出发点,逐个应用之前准备好的补丁文件,最后会生成一个新的合并提交对象,从而改写experiment的提交历史,使它成为master分支的直接下游。
衍合最后生成的快照,其实和普通的三方合并的快照内容一模一样。虽然最后整合得到的结果没有任何区别,
但是衍合能产生一个更为整洁的提交历史。如果观察一个衍合过的分支的历史记录,看起来会更清楚:仿佛所有修改都是在一跟线上先后进行的,尽管实际上他们原本是同时并行发生的。
一般我们使用衍合的目的,是想要得到一个能在远程分支上干净应用的补丁,比如某些项目你不是维护者,但是想帮点忙的话,最好使用衍合:先在自己的一个分支里进行开发,当准备向主项目提交补丁的时候,根据最新的origin/master进行一次衍合操作然后再提交,这样维护者就不需要做任何工作(实际上是把解决分支补丁同最新主干代码之间冲突的责任,转化为由提交补丁的人来解决),维护者只需要根据你提供的仓库地址进行一次快进合并,或者直接采纳你提交的补丁。
======== 衍合的风险=========
一旦分支的提交对象发布到公共仓库,就千万不要对该分支进行衍合操作。
进行衍合的时候,实际上抛弃了一些显存的提交对象而创造了一些类似但不同的新的提交对象,
如果你把原来分支中的提交对象发布出去,并且其他人更新下载后在其基础上开展工作,而稍后你又用git rebase
抛弃这些提交对象,把新的重演后的提交对象发布出去的话,你的合作者就不得不重新合并他们的工作,这样当你再次从他们那里获取内容的时候,提交历史就会变得一团糟。
https://git-scm.com/book/zh/v1/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E8%A1%8D%E5%90%88
/workspace/xxx-xx-cms:the-channel-sort$ git push origin the-channel-sort
To git@bitbucket.org:xxx-xxx-cms/xxx-xx-cms.git
! [rejected] the-channel-sort -> the-channel-sort (non-fast-forward)
error: failed to push some refs to ‘git@bitbucket.org:xxx-xxx-cms/xxx-xx-cms.git‘
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. ‘git pull’) before pushing again. See the
‘Note about fast-forwards’ section of ‘git push –help’ for details.
/workspace/xxx-xx-cms:the-channel-sort$ git fetch
remote: Counting objects: 13, done.
remote: Compressing objects: 100% (13/13), done.
remote: Total 13 (delta 9), reused 0 (delta 0)
Unpacking objects: 100% (13/13), done.
From bitbucket.org:xxx-xxx-xxx/xxx-xx-cms
* [new branch] production-deployment -> origin/production-deployment
* [new branch] staging -> origin/staging
/workspace/xxx-xx-cms:the-channel-sort$ git rebase origin/the-channel-sort
First, rewinding head to replay your work on top of it…
Applying: 重构代码
/workspace/xxx-xx-cms:the-channel-sort$ gitg
/workspace/xxx-xx-cms:the-channel-sort$ git push
Counting objects: 35, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (18/18), done.
Writing objects: 100% (18/18), 2.29 KiB, done.
Total 18 (delta 14), reused 0 (delta 0)
remote:
remote: View pull request for the-channel-sort => master:
remote: https://bitbucket.org/xxx-xxx-cms/xxx-xx-cms/pull-requests/21?t=1
remote:
To git@bitbucket.org:xxx-xxx-cms/xxx-xx-cms.git
841dda2..95cdf0d the-channel-sort -> the-channel-sort
找到文件的所有修改者
git blame [file_name]