git命令详解
Git基本概念
Git是什么
Git是一个分布式代码管理工具,而SVN则是集中式代码管理工具。
- 集中式: 所有的代码都保存在中央服务器,所以提交必须依赖网络,协同工作的人们都通过客户端连接到这台服务器,取出最新的文件或者提交更新
- 分布式: 每个终端都是一个仓库,客户端并不只提取最新版本的文件快照,而是把原始的代码仓库完整的镜像下来,每一次的提取操作,实际上都是一次对代码仓库的完整备份。因此可以在本地进行提交,并不需要依赖网络。
![](https://img.haomeiwen.com/i10239771/0ba70fd9497b4073.jpg)
工作区域
- 工作区: 实际的工作目录
- 暂存区: 代码add以后暂时存储的区域
- 仓库区: 分为本地仓库和远程仓库。 本地仓库是commit以后存储的区域, 远程仓库是push以后存储的区域
commit节点
每次Git提交以后都会生成一个节点,每个节点都会有一个哈希值作为一个唯一标示,多次提交就会形成一个线性节点链, 如下图所示,C2是最后一个提交节点,那么C2会包含前面C1和C0的提交内容。右边则是每次提交对应的哈希值
![](https://img.haomeiwen.com/i10239771/9cf9bf8ffd937bdc.jpg)
HEAD
HEAD相当于一个指针,它可以指向任意一个节点,它指向的那个节点就是当前工作节点。如上图所示,当HEAD指向C2,那么当前工作目录就是C2。
分支
分支可以让开发分多条主线同时进行,每条主线互不影响
假如将整个项目比作一个单机游戏,节点就是玩家保存的进度,HEAD指的就是玩家当前选择的那个进度,而分支可以认为是不同的玩家在玩这个游戏的历程。
Git命令详解
1. 初始化
1.1 初始化本地仓库
![](https://img.haomeiwen.com/i10239771/5599108ca771b14d.png)
1.2 关联远程仓库
git remote add <自定义仓库名> + 仓库ssh地址
git init初始化仓库以后需要进行git remote操作,实现本地和远程仓库绑定,这样才算是完整创建本地仓库
![](https://img.haomeiwen.com/i10239771/4f8eee9f231dcae4.png)
1.3 克隆远程仓库到本地
可以通过git clone的方式直接将远程仓库克隆到本地,此时远程仓库名默认为origin。
![](https://img.haomeiwen.com/i10239771/b7e906e4e8f5c29f.png)
2. 查看文件状态
2.1 查看文件状态
git status
![](https://img.haomeiwen.com/i10239771/a918cc338ecadccf.png)
2.2 查看文件状态简览
git status -s
相对于git status来说显示的内容更简单直观一点
- 新添加的未跟踪的文件前面有??, 即test5.txt
- 新添加的文件已经放入暂存区的,文件前面会显示A, 即test4.txt
- 文件被修改但是没有放入暂存区,右边会出现M, 即 test2.txt和test3.txt
- 文件被修改并且已经被放入暂存区,左边会出现M, 即test.txt
- 文件被删除但是没有放入暂存区,右边会出现D
- 文件被删除并且已经被放入暂存区,左边会出现D
![](https://img.haomeiwen.com/i10239771/1525070f2233f89f.png)
3. 查看修改
3.1 查看工作区所有文件的修改
git diff
diff --git a/git_test_demo/README.md b/git_test_demo/README.md
这一行显示diff下两个文件的对比。 a版本指的是修改前的README.md, b版本指的是修改后的README.mddeleted file mode 100644
删除了文件 100指的是普通文件,644代表文件权限
Index e69de29..000000
index后面的两个数字表示两个文件的hash值,因为是删除,所以后面的数字hash值为000000。diff--git a/git_test_demo/test.txt b/git_test_demo/test.txt
这一行显示diff下两个文件的对比。 a版本指的是修改前的test.txt, b版本指的是修改后的text.txtIndex 5d58fcd..f316c8d 100644
index后面的两个数字表示两个文件的hash值(index区域的5d58fcd与工作区的f316c8d对象对比)--- a/git_test_demo/test.txt
+++ b/git_test_demo/test.txt
---表示修改前, +++表示修改后@@ -2,3 +2,4 @@
该行表示接下来下面显示的内容所在的位置。
-表示修改前, +表示修改后
-2,3 表示修改前test.txt文件从第2行显示,一直到第4行(2位起始行, 3位向后偏移的行数。即显示修改内容从第2行到第4行)
+2,4 表示修改后test.txt文件从第2行显示,一直到第5行(2位起始行, 3位向后偏移的行数。即显示修改内容>从第2行到第5行)
10239771-2fb3db1bfd16f303.png
3.2 查看暂存区所有文件的修改
git diff --staged
![](https://img.haomeiwen.com/i10239771/367ae18a1b816b15.png)
3.3 查看两次提交之间的差异
git diff <commit id1> <commit id2>
![](https://img.haomeiwen.com/i10239771/e20042ca6ab315f6.png)
3.4 查看两个分支之间的差异
git diff <branch1> <branch2>
![](https://img.haomeiwen.com/i10239771/308811adf741c7b4.png)
3.5 查看指定提交的修改内容
git show <commit id>
![](https://img.haomeiwen.com/i10239771/af04fb4175ed14cf.png)
3.6 查看指定文件的修改历史
git blame <file>
![](https://img.haomeiwen.com/i10239771/cc7b0f860a8539fb.png)
3.7 查看最近N次提交的修改内容
git log -p -N
![](https://img.haomeiwen.com/i10239771/c630aa16830a7ba6.png)
4. 查看提交记录
4.1 查看当前分支的历史提交记录
git log
![](https://img.haomeiwen.com/i10239771/dec0f929ba8aa6ca.png)
4.2 简洁的方式查看提交历史
git log --pretty=oneline
![](https://img.haomeiwen.com/i10239771/843fa3ffcb3016c2.png)
4.3 查看分支合并图
git log --graph
![](https://img.haomeiwen.com/i10239771/f91c9176191d12a2.png)
4.4 查看所有的操作记录
git reflog
任何的操作记录都会显示在reflog上面
显示内容为Commit id + 执行的命令 + 提交描述
10239771-6f72efa3f1cf3170.png
4.5 查看指定提交记录是在哪个分支提交的
git branch --contains <commit id>
![](https://img.haomeiwen.com/i10239771/aabc6cdd10fe8f3e.png)
5. 添加文件
![](https://img.haomeiwen.com/i10239771/82b00ea81455e051.png)
![](https://img.haomeiwen.com/i10239771/503c72f9badc8757.png)
![](https://img.haomeiwen.com/i10239771/24aa6eee5bcb8c60.png)
当前目录下修改了三个文件test.txt, test2.txt, test3.txt, 新增了test4.txt, 移除了README.md
5.1 暂存工作区所有的文件
git add . / git add -A / git add --all
![](https://img.haomeiwen.com/i10239771/a586385729f1716c.png)
![](https://img.haomeiwen.com/i10239771/17e2415bdfa87990.png)
5.2 暂存工作区指定的文件
git add <file1> <file2>
![](https://img.haomeiwen.com/i10239771/d20dde904924fb24.png)
5.3 暂存工作区指定目录的所有文件
git add {directory}
![](https://img.haomeiwen.com/i10239771/f36b270d011ac75b.png)
5.4 暂存工作区所有文件,不包含删除的文件
git add *
![](https://img.haomeiwen.com/i10239771/dc72ce1380fd2c90.png)
5.5 暂存工作区所有文件,不包含新增的文件
git add -u
![](https://img.haomeiwen.com/i10239771/a5c406e4de986282.png)
6. 分支
6.1 查看本地分支列表
git branch (带星号指的是当前的分支)
![](https://img.haomeiwen.com/i10239771/85aa0eb6eaede329.png)
6.2 查看远程分支列表
git branch -r
![](https://img.haomeiwen.com/i10239771/84bdb4ccbfa35159.png)
6.3 查看所有的分支列表(包括本地和远程)
git branch -a
![](https://img.haomeiwen.com/i10239771/d42470959813b726.png)
6.4 查看本地每个分支最后一次提交
git branch -v
![](https://img.haomeiwen.com/i10239771/047702c26430b443.png)
6.5 查看本地每个分支最后一次提交,并且与远程分支进行比较
git branch -vv
![](https://img.haomeiwen.com/i10239771/2b5ea1cc373dfa40.png)
6.6 创建分支
git branch <branch>
![](https://img.haomeiwen.com/i10239771/ce770af7ffa89a3f.png)
6.7 删除指定分支
git branch -d <branch>
![](https://img.haomeiwen.com/i10239771/1fa57bab3037d433.png)
6.8 强制删除指定分支
git branch -D <branch>
![](https://img.haomeiwen.com/i10239771/d0a18606b326ac8a.png)
6.9 删除远端分支
git push origin --delete <branch>
![](https://img.haomeiwen.com/i10239771/9d432e298002452d.png)
6.10 切换到上一个分支
git checkout -
![](https://img.haomeiwen.com/i10239771/5ca564813bc8dd7c.png)
6.11 切换分支
git checkout <branch>
![](https://img.haomeiwen.com/i10239771/7745611457f9c31a.png)
6.12 创建分支并且切换到该分支
git checkout -b <branch>
等价于git branch <branch> + git checkout <branch>
![](https://img.haomeiwen.com/i10239771/258e827900c8d8f7.png)
7. 提交
7.1 提交暂存区的文件到本地仓库
git commit -m "message"
![](https://img.haomeiwen.com/i10239771/7ddecdbdbb418f23.png)
7.2 跳过暂存区直接执行提交
git commit -a -m "message" / git commit -am "message"
这种方式可以直接提交工作区修改后的文件,但是新添加的文件是不会提交的,仍然需要先add到暂存区。
![](https://img.haomeiwen.com/i10239771/6cb1b77546e72146.png)
![](https://img.haomeiwen.com/i10239771/89dbf8174b78473b.png)
7.3 修改之前已经提交的结果
git commit --amend
第二次提交将 代替 上一次提交的结果。适用于提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了的情况。
![](https://img.haomeiwen.com/i10239771/8aadca55c3f35aa1.png)
7.4 将本地提交推送至远端
git push origin <branch>
![](https://img.haomeiwen.com/i10239771/0f7eb3f11c2d56d2.png)
7.5 强制提交到远端
git push origin <branch> --force
以下图为例, 将上面那次commit给撤销以后,然后执行git push origin cdf2发现无法推到远端仓库。
所以执行了git push origin cdf2 --force强制将远端仓库的那次提交也给撤销掉
![](https://img.haomeiwen.com/i10239771/36416c7d2fff1021.png)
7.6 将修改提交到远端指定的分支
git push origin <commit id>:<branch>
以下图为例
- 在cdf2的分支下面提交了一个test4.txt文件
- 将test4.txt文件推到了远端cdf4的分支上
![](https://img.haomeiwen.com/i10239771/df06c11af9c70a75.png)
8. 拉取
8.1 拉取远端分支的最新代码
git fetch
git fetch --depth=N
只拉取最近N次的commit, 这样可以加快拉取速度。 但是由于只拉取最近N次的commit,所以相应的本地也只能看到最近的N次commit。
git fetch 会先将远端的代码拉取下来保存到FETCH_HEAD中,然后通过git merge的方式将FETCH_HEAD的代码merge到当前本地分支
![](https://img.haomeiwen.com/i10239771/3b6fb42ad5ecdee9.png)
![](https://img.haomeiwen.com/i10239771/b42dbc079225ef6d.png)
8.2 拉取远端分支的最新代码, 并且合并到本地分支
git pull
git pull则是git fetch + git merge的操作, 直接更新本地分支的代码
![](https://img.haomeiwen.com/i10239771/6e2800075d4eca44.png)
![](https://img.haomeiwen.com/i10239771/e70bb2bb48234a48.png)
![](https://img.haomeiwen.com/i10239771/83faf50e1da98b80.png)
8.3 拉取远端分支的最新代码,并且合并到本地分支
git pull --rebase
当本地没有任何提交记录,那么git pull = git pull --rebase。
当本地提交了一个节点,远端同一个分支也更新了节点
通过git pull的方式会产生一个merge的提交记录
如右下图所示
![](https://img.haomeiwen.com/i10239771/352da7937889055e.png)
![](https://img.haomeiwen.com/i10239771/b1928e38e91e38c3.png)
通过git pull --rebase的方式,则会让整个提交记录看起来更线性。
![](https://img.haomeiwen.com/i10239771/4d6c6c772d5cbfbb.png)
![](https://img.haomeiwen.com/i10239771/e54f927e27b67360.png)
9. 回退
9.1 清空暂存区
git reset HEAD/ git reset --mixed
![](https://img.haomeiwen.com/i10239771/fd725238a50a40a6.png)
![](https://img.haomeiwen.com/i10239771/828f73626b07bbe2.png)
9.2 将HEAD回退N个节点
git reset HEAD~N
例如N=2,那么HEAD将往前推2个节点,会指向倒数第三个节点。 回退以后保留修改文件
![](https://img.haomeiwen.com/i10239771/4f831cc8ce76d49a.png)
9.3 重置所有文件到未修改的状态
git reset --hard
![](https://img.haomeiwen.com/i10239771/1531c50255da8815.png)
9.4 将HEAD回退一个节点
git reset --hard HEAD^ / git reset --hard HEAD~1
![](https://img.haomeiwen.com/i10239771/ceea4498816890a4.png)
9.5 将HEAD回退到指定的节点
git reset --hard <commit id>
![](https://img.haomeiwen.com/i10239771/a0e5d62046b12f5d.png)
9.6 撤销工作区指定文件的改动
git checkout -- <file> / git restore <file>
![](https://img.haomeiwen.com/i10239771/181f3ac408a4792d.png)
![](https://img.haomeiwen.com/i10239771/c7a0b711dc7865d4.png)
9.7 将HEAD指向指定节点
git checkout <commit id>
![](https://img.haomeiwen.com/i10239771/d805407b3399704a.png)
![](https://img.haomeiwen.com/i10239771/daf960bd4d8cfd28.png)
9.8 将HEAD指向前一个节点
git checkout HEAD^
![](https://img.haomeiwen.com/i10239771/de0b7bcccae87622.png)
![](https://img.haomeiwen.com/i10239771/450287df67caf58d.png)
9.9 将HEAD往前移动N个节点
git checkout HEAD~N
例如N=2,那么HEAD将往前推2个节点,会指向倒数第三个节点
![](https://img.haomeiwen.com/i10239771/851d7c3292d095ec.png)
![](https://img.haomeiwen.com/i10239771/86d861ffcad3eccf.png)
9.10 还原指定节点的修改
git revert <commit id>
revert以后会将原来的修改回退掉,并且新增一条提交记录
![](https://img.haomeiwen.com/i10239771/9070035e50ae6c23.png)
9.11 还原上次的提交
git revert HEAD
![](https://img.haomeiwen.com/i10239771/bd448aaf71f81c95.png)
10. 保存
10.1 保存当前修改的内容
git stash
![](https://img.haomeiwen.com/i10239771/4a1f7d79e4a40fcf.png)
10.2 查看保存的记录列表
git stash list
![](https://img.haomeiwen.com/i10239771/8dc0f5c209c3117a.png)
10.3 将上一次保存的内容恢复到工作区
git stash apply
![](https://img.haomeiwen.com/i10239771/f202a24a01c01e9f.png)
![](https://img.haomeiwen.com/i10239771/6a366f1daa8d9a70.png)
10.4 删除stash里面上一次保存的记录
![](https://img.haomeiwen.com/i10239771/64c108153aa2758c.png)
10.5 上一次保存的内容恢复到工作区,并且删除对应的记录
git stash pop
![](https://img.haomeiwen.com/i10239771/3d32ad8bd7b31477.png)
10.6 清空stash里面所有保存的记录
git stash clear
![](https://img.haomeiwen.com/i10239771/c68b7390575529ce.png)
10.7 删除stash里面指定index的那一条记录
git stash drop <index>
![](https://img.haomeiwen.com/i10239771/33f85970be9f026c.png)
11. 标签
11.1 在指定节点上创建标签
git tag <tag name> <commit id>
![](https://img.haomeiwen.com/i10239771/f54663656e14f075.png)
11.2 查看所有标签
git tag
![](https://img.haomeiwen.com/i10239771/94287a4a99bea183.png)
11.3 删除本地标签
git tag -d <tag name>
![](https://img.haomeiwen.com/i10239771/3c56264d04bb31b6.png)
11.4 将本地指定标签推送到远端
git push origin <tag name>
![](https://img.haomeiwen.com/i10239771/d579e590cd020f8f.png)
11.5 将本地所有标签推送到远端
git push origin --tags
![](https://img.haomeiwen.com/i10239771/4b0281ec24c80b49.png)
12. 合并
合并整体的链路比较复杂,并且在命令行中不好直观呈现,下一节做比较的时候再详细给出
12.1 将指定的提交节点复制到当前最新的节点上
git cherry-pick <commit id>
执行git cherry-pick <commitid>将其他分支的指定commit记录复制过来提交到当前分支
![](https://img.haomeiwen.com/i10239771/3fd53ec972265a6a.png)
12.2 将指定分支的提交记录复制到当前分支
git merge <branch>
- 执行git merge cdf将cdf分支的代码合并过来
- 产生冲突以后,将文件冲突解决掉
- 执行git add .命令
- 执行git merge --continue。
- 然后就会产生一条merge的commit记录
![](https://img.haomeiwen.com/i10239771/90e937092fc5550c.png)
![](https://img.haomeiwen.com/i10239771/3e59aaaf8c5e363f.png)
12.3 将指定分支的提交记录复制到当前分支,并且保持线性的提交记录
git rebase
- 执行git rebase cdf将cdf分支的代码合并过来
- 产生冲突以后,将文件冲突解决掉
- 执行git add .命令
- 执行git rebase --continue。
- rebase以后的提交记录更具线性
![](https://img.haomeiwen.com/i10239771/fa916914c74d082e.png)
git rebase之前的commit记录
![](https://img.haomeiwen.com/i10239771/9f93eeb9af7e045c.png)
git rebase 之后的commit记录
![](https://img.haomeiwen.com/i10239771/3d7337c8af4cd42b.png)
12.4 将多次的提交合并为一次提交
12.4.1 git rebase -i HEAD~N
将最近的N个commit合并为同一个commit。
12.4.1.1 执行前:
![](https://img.haomeiwen.com/i10239771/c4dfe5f8e899a27b.png)
12.4.1.2 执行后:
![](https://img.haomeiwen.com/i10239771/a638e412ec9f2d1c.png)
12.4.2 git rebase -i <commit id1> <commit id2>
将<commitid1>到<commitid2>之间的提交合并成一个提交,左开右闭。所以如果要合并最近的三个提交,那么只需要<commitid1>填倒数第四个提交的commitid, <commitid2>填最近一个提交的commitid即可
12.4.2.1 执行前:
![](https://img.haomeiwen.com/i10239771/5e2e78ff23e8639b.png)
12.4.2.2 执行后:
![](https://img.haomeiwen.com/i10239771/d49d287188e3e73b.png)
Git相似命令比较
1. 「git reset HEAD^」 VS 「git checkout HEAD^」
1.1 git reset HEAD^
git reset HEAD^在当前分支将HEAD指向了前一个节点,这个时候可以直接执行push origin <branch> --force就可以更新远端分支
![](https://img.haomeiwen.com/i10239771/3c439064281055d0.png)
1.2 git checkout HEAD^
git checkout HEAD^则是脱离了当前分支,然后将HEAD指向了前一个节点。但是main分支最新的commit依然是C4, 这个时候执行push origin <branch> --force会提示Everything up-to-date。
![](https://img.haomeiwen.com/i10239771/2eb9533b46985fac.png)
2. 「git reset HEAD^」VS 「git revert HEAD」
2.1 git reset HEAD^
git reset HEAD^将本地分支最新的commit记录指向了前一个节点,最新的commit已经变成了C3,这个时候可以直接执行push origin <branch> --force就可以更新远端分支
![](https://img.haomeiwen.com/i10239771/20d172b2c7053388.png)
2.2 git revert HEAD^
git revert HEAD则只是将上一次的提交的记录回滚,并且重新提交了一遍,虽然最后的结果跟reset一样,但是在分支上面会新增一个节点
![](https://img.haomeiwen.com/i10239771/8cdb183dbd8a7bd8.png)
3. 「git cherry-pick」 VS 「git merge」 VS 「git rebase」
3.1 git cherry-pick
下图HEAD指向了main, 我们想将cdf分支的C3复制到当前所在位置的话,就可以使用cherry-pick的方式
![](https://img.haomeiwen.com/i10239771/c510c12208af4590.png)
如图所示,将cdf分支上C3的提交cp到main分支变成了C3',C3'跟C3就只有提交的内容一样,属于不同的两次提交
![](https://img.haomeiwen.com/i10239771/3c97894451bbb648.png)
3.2 git merge
下图HEAD 是指向了 main,我们想将 cdf 分支的代码合并到 main 分支上来,那么执行 git merge cdf
![](https://img.haomeiwen.com/i10239771/9205d8e7b90b8bce.png)
合并之后,多了一个C6节点,这个节点的父节点有两个,分别是C4和C5。 main和HEAD指向了合并后的新节点
![](https://img.haomeiwen.com/i10239771/87fbcbc8a83e63ce.png)
3.3 git rebase
下图HEAD指向了main, 我们想将cdf 分支的代码合并到main分支,但是又想让提交的记录比较整洁,这个时候就可以使用git rebase的方式
![](https://img.haomeiwen.com/i10239771/e3759a979bba5156.png)
rebase,顾名思义就是重新以XX为父节点。重新创建一个"分支",将需要rebase的分支提交节点给复制过来,然后再将当前分支的节点放到新"分支"最新的节点上。并且HEAD指向了新"分支"(注:这里的分支打个双引号是因为它其实并不是一个真正意义上的分支,它没有分支名,只有HEAD),而且原来分支节点依然还存在,如果还想用到之前的节点,可以通过checkout 对应的commit id即可
![](https://img.haomeiwen.com/i10239771/e048ff5b090d6f61.png)
Q&A
1. 应该如何回退自己的git操作
1.1 发现自己提交的代码有点问题, 想要撤回上一次的提交,但是又想保留原先的修改,那么执行git reset --mixed或者git reset --soft 。 git reset默认就是mixed
1.2 发现自己的提交就是有问题的,想要撤回上一次的提交,并且不想保留原先的修改,那么可以执行git reset --hard
1.3 如果我们想要撤回远端分支的提交,但是远端分支又是一个protected的分支,那么我们只能选择git revert的方式将修改还原,但是会在分支上新增一次提交记录
2. 应该怎么保存自己的代码?
2.1 一个feature开发完成或者一个bug修改完成,这个时候需要切换分支去做其他事情,那么可以commit到本地仓库,然后推到远端自己建的分支上面。 但是后续如果有些修改但是又不想再增加commit了,那么可以通过git commit -amend的方式来覆盖上一次commit的记录
2.2 有时候工作区文件改了一半,但是又不想增加一个commit,但是需要把远端的最新代码拉下来又发现有冲突拉代码失败。 这个时候就可以先通过git add的方式放到暂存区,然后git stash将文件保存起来。
3. 如何快速查到一段代码的修改记录?
3.1 如果只是想看这段代码是什么时候提交的,可以通过git blame -L N, +M --<file>查看
其中N代表是从第N行开始, M代表一共要看M行代码, file就是对应的文件名
![](https://img.haomeiwen.com/i10239771/fcba146f80cb90b3.png)
3.2 如果需要看到某一行代码的修改记录,那么可以通过git log -L N, +M:<file>查看
其中N代表是从第N行开始, M代表一共要看M行代码, file就是对应的文件名
![](https://img.haomeiwen.com/i10239771/2aa44abdf9a8daca.png)
3.3 AndroidStudio自带的git功能也非常好用,选中一段代码,右键Git->Show History for Selection就可以查看所有的修改记录
![](https://img.haomeiwen.com/i10239771/4b664c6ed525aa92.png)
4. 如何快速查找某个人的提交记录?
git log --author=<email>
![](https://img.haomeiwen.com/i10239771/1aefc40b3e54f43d.png)
5. 如何快速查找某个commit?
- 通过git log --grep <key> 关键字搜索的方式搜索出所有相关的commit
- 找到对应的commitid
-
通过git show <commitid> 就可以找到对应的修改记录
10239771-b02b0fa86e073da7.png
6. 如何知道自己的某个commit 都合入了哪些分支 以及哪些版本(tag)?
如果知道对应的commitid,那么通过git branch --contains <commitid>
![](https://img.haomeiwen.com/i10239771/628a97c4ffc07471.png)
如果并不知道commitid,那么需要先通过git log --all --grep <key>的方式找到对应的提交记录,然后通过git branch --contains <commitid>
![](https://img.haomeiwen.com/i10239771/d28dfa5b34336f14.png)
7. git reset --hard之后代码丢了,怎么恢复
7.1 如果你的代码现在在工作区或者是暂存区,你不小心执行了git reset --hard命令,那么真的是神仙难救,所以如果工作区有代码,切忌不要执行git reset --hard方法
7.2 如果你的代码已经push到了远程仓库,你不小心执行了git reset --hard命令,那么只需要git pull就可以恢复。如下图所示
![](https://img.haomeiwen.com/i10239771/06c641c49e3a0777.png)
![](https://img.haomeiwen.com/i10239771/f062963430d9f7ba.png)
![](https://img.haomeiwen.com/i10239771/f11f9b773d5a17a8.png)
7.3 如果你的代码已经push到了远程仓库,你不小心执行了git reset --hard命令,并且还强制推送到了远端,那么可以执行下面的步骤,如下图所示
- 通过git reflog查看所有的操作记录
- 找到撤销之前的那条commit
- 通过git reset --hard <commitid>
- 通过git push origin <branch> 的方式恢复远端分支
通过git reflog查看所有的操作记录,找到撤销之前的那条commit
![](https://img.haomeiwen.com/i10239771/1206c688391d81ed.png)
通过git reset --hard <commitid>,git push origin <branch> 的方式恢复远端分支
![](https://img.haomeiwen.com/i10239771/b77a338e9f11cb0f.png)
8. 新增的文件刚好命中了.gitignore的规则,怎么提交
![](https://img.haomeiwen.com/i10239771/c22f424bc994bbcb.png)
当你新增的文件或者修改的文件刚好命中了gitignore的规则,那么你执行git add命令的时候会有上面这段提示。通过git add -f <file>的方式就可以添加到暂存区。
![](https://img.haomeiwen.com/i10239771/5f3b8526b83a89d8.png)
当然如果觉得gitignore的规则不合理,修改.gitignore文件即可
9. 一个文件里面有多个bug单对应的修改或者是有些修改是测试代码,该怎么提交指定的内容
9.1 通过git add -p <file>的方式筛选出要提交的代码,如下图所示。
-
在test10.txt文件中新增四行,然后保存。
image.png
image.png
-
执行git add -p test10.txt的命令
image.png
- 这里有几个命令需要执行
a. y: 同意这段修改放入暂存区
b. n: 不同意这段修改放入暂存区
c. q: 退出
d. a: 同意这段修改和这个文件中所有的其他修改都放入暂存区
e. d: 不同意这段修改以及这个文件中所有的其他修改放入暂存区
f. e: 自定义选择放入暂存区
g. ?: 打印帮助 - 选择e进入编辑页面
a. 新增行,不想提交(但是变更仍然在工作区)。删除整行
b. 删除行,不想提交。用空格符" "代替"-"字符。
c. 变更行,不想提交。上面两个结合——对于"+"所在行整行删除,对于"-"所在行,用空格符" "代替"-"字符
![](https://img.haomeiwen.com/i10239771/aeaeeada4057b7d8.png)
-
删除「add new line 2」和「add new line3」然后保存。然后执行git commit将test10提交到本地仓库
image.png
-
根据commitid查看修改记录
image.png
9.2 使用sourcetree提交
执行命令行来提交指定的内容多少是有点不直观,并且不易上手,采用sourcetree的方式就非常直观,选中指定的提交的内容然后点击暂存行即可
![](https://img.haomeiwen.com/i10239771/4aefec145da7777f.png)
10. git push origin <branch> --force以后,如何回退
git push origin <branch> --force以后,远端的分支节点已经发生了改变,但是本地分支依然是有以前的commit记录,所以先使用git reflog找到之前的操作记录,通过git reset -hard <commitid>的方式回退到当时的版本, 然后git push origin <branch>来更新远端分支