很久之前简单写过一篇关于Git工具 SourceTree 的使用的文章(传送门),sourceTree之类的工具是git操作更佳直观,然而最原始的git操作,都是用git命令来完成的,而且使用git命令也更灵活更强大。所以今天特地抽空把git命令的使用总结了一下,希望大家多多交流,发现问题也请在评论区指正。
tips:篇幅略长,可以通过目录辅助浏览
克隆/ 暂存/ 提交/ 拉取/抓取/推送
克隆远程仓库到本地:
git clone 远程地址
查看未暂存文件修改情况:
git diff
查看暂存区的文件修改内容:git diff --cached
或git diff --staged
暂存文件:git add 文件路径
或git add .
撤销未暂存文件的修改:git checkout -- 文件名
(操作不可逆)
恢复删除的文件:step1:git reset HEAD 文件名
撤销删除文件的暂存 step2:git checkout -- 文件名
将删除的文件进行恢复
取消文件暂存:git reset HEAD 文件名
查看commit日志:git log
或git log -3
(显示3条)
查看简约日志:git log --oneline -3
(只显示commit-hash 和 commit info)
查看最近一次提交的差异:git log -p -1
查看所有差异:git log -p
提交暂存:
git commit
暂存文件并提交:git commit -a
添加描述提交:git commit -m "内容描述"
暂存添加描述提交:git commit -a -m "内容描述"
`
拉取远端:
git pull
抓取分支:
git fetch origin 分支名
抓取远端所有分支:git fetch
推送至远端:
git push origin 分支名
跟踪远端分支:git push -u origin 分支名
查看远端仓库地址:git remote -v
操作 branch
查看状态:
git status
查看简写状态:git status -s
(M 修改, A 添加, D 删除, R 重命名, ?? 未追踪)
查看分支:git branch
查看所有分支最后一次提交:git branch -v
创建分支:git branch 分支名
检出分支:git checkout 分支名
创建 + 检出分支:git checkout -b 分支名
合并某分支到当前分支:git merge 分支名
合并某分支到当前分支并添加注释信息:git merge 分支名 --no-ff -m "内容描述"
删除分支:git branch -d 分支名
查看远程分支:git branch -a
删除远程分支:git push origin --delete 分支名
或git push origin :分支名
操作 tag
显示所有标签:
git tag
创建标签:git tag -a 标签名 -m “标签描述”
删除本地标签:git tag -d 标签名
显示标签描述:git show 标签名
给之前的commit 创建tag:git tag -a 标签名 -m “标签描述” commit-hash
将标签推送到远端:git push origin 标签名
推送所有标签:git push origin --tags
删除远程标签:git push origin -d 标签名
或git push origin --delete tag
标签名
合并 (merge)/变基(衍合)(rebase) / 摘樱桃(cherry-pick)
三个操作都是分支间的操作, 每项操作都有可能得到代码冲突,遇到冲突的情况一定要先解决掉冲突才可以commit、push到远端。
- 合并分支:
git merge 分支名
(合并分支会在原来的基础上新增一个commit,提交log是按时间排序)
- 变基分支:
git rebase 分支名
(变基分支不会新增一个commit , 提交log是按两个分支的提交记录续接下去的) - 摘取一个commit:
git cherry-pick 其他分支的commit-hash
(相当于直接把别的分支的某些提交直接摘到当前分支) - 摘取多个commit:
git cherry-pick commit-hash1..commit-hash2
(1到2之间的commits,不包括1)或git cherry-pick commit-hash1^..commit-hash2
(1到2之间的commits,包括1)
解决冲突
当使用上述任意方法合并代码时,都有可能造成冲突,有冲突时终端会有如下提示:
CONFLICT (content): Merge conflict in fileName
这时候可以vim到或open该文件,会发现类似形式的冲突:
<<<<<<< HEAD
master 1
=======
故意制造冲突
>>>>>>> mywork
其中<<<<<<< HEAD
之下为当前分支的改动,=======
与>>>>>>>
之间是另一分支的改动,手动解决冲突即可,如按当前更改解决冲突,文件就变成了
master 1
其他部分手动删除掉。
解决完之后,重新git add .
-> git commit -m “info”
-> git push
。
git 上的撤销回滚操作
回滚到某次提交
git checkout commit-hash
这步操作会使HEAD成为一个单独的分支,而不是指向一个分支,然后可以检出一个新的分支到此次提交的版本
git checkout -b NewBranch
这时候NewBranch这个分支就代表了指定commit之前的版本。
回滚某个文件到指定commit的版本
git checkout commit-hash file
这样会改变工作区的状态,需要重新暂存和提交保存更改
重提操作 revert
加入项目中的某次提交引入的一个bug,可以使用git revert 命令进行撤销,完整步骤
git revert commit-hash
-> i 编辑info -> ESC : wq 回车 -> git push
revert操作是一个线性操作,撤销某个commit本身,会有工作区的一个改动,然后进行暂存提交,HEAD会顺序向前,跟一般性的改动一样。但是如果你撤销的commit之后又有很多commit,这时候很可能会出现不少冲突,这是revert的一个缺点。
重置操作 reset
- 取消某文件的暂存状态:
git reset file
(此操作将文件状态从stage重置为unstage,即回到git add .
前的状态)。
- 取消工作区所有文件的暂存状态:
git reset
。 - 清空所有工作区的改动:
git reset --hard
(不可逆,慎重)。 - 重置项目至某个提交:
git reset commit-hash
。 (真正意义上的回滚,该commit之后的所有的提交内容都会出现在暂存区,同时失去这些提交)。 - 重置项目至某个提交且清空工作区:
git reset --hard commit-hash
(失去该提交后的所有提交,且不保留改动内容在暂存区和工作区,不可逆,危险操作,慎重)。
注意(重要!):在执行reset commit操作时,请确保至作用本地的commit,不然可能会失去远端公共的团队其他成员在内的一些提交,可以使用revert代替,这样不会失去commit的历史。
移除未追踪的文件
显示将移除的文件:git clean -n
移除未追踪的文件:git clean -f
(不会移除.gitignore里忽略的未追踪的文件)
移除指定路径下未追踪的文件:git clean -f path
移除工作区未追踪的文件和目录:git clean -df
移除包括忽略文件的未追踪文件:git clean -xf
常见使用场景
场景1,本地编辑了一些垃圾代码和引入了错误文件,可以使用下面操作清除
git reset --hard -> git clean -f
但要保证这些内容确定不想要了,以免失去劳动成果后悔莫及。
场景2,本地进行了一个提交,想要删除掉,可以使用命令
git reset --hard HEAD~1
(数字表示回退的commit数,1表示会退到上一个commit,带–hard会删除被回退的内容,去掉–hard可以保留修改到工作区,下同)
或
git reset --hard commit-hash
场景3,向远端提交了一个错误的commit,需要删除或修改
涉及到操作远端的commit,就要稍微谨慎些了,因为有可能会影响到团队其他成员。所以建议尽量避免使用reset(保证安全的前提下也可以用),推荐使用revert,它不会删除提交记录这样可以给你再次反悔的机会(但也不要有恃无恐…),具体操作
1.git revert HEAD~2
(2表示重提的是第二个提交)
或
git revert -i commit-hash
2.git push origin branchName
补充:第一步之后往往会有冲突,这时需要现在本地把冲突解决一下然后执行 git add .
再执行 git revert --continue
,这时候进入编辑模式输入“i”开始编辑commit info,编辑完成后,在英文输入状态下按ESC然后“:wq”回车,整个revert过程就结束了,这时候git log
可以看到该分支上有个关于revert的新的commit。还有如果只是你自己用的一条分支,确定要删除提交,可以放心用reset,这样git树会比较干净。
场景4,提交了几个少量修改的commit,想要把几个commit合并成一个
首先
git log --oneline
结果:
16b8053 (HEAD -> fixBug) 用 revert 做了修改
4e1c7e4 Revert "commit1"
9194522 (origin/fixBug) commit2
2d65e33 commit1
比如想合并前三条,执行下面命令进入rebase编辑模式:
git rebase -i HEAD~3
结果:
pick 9194522 commit2
pick 4e1c7e4 Revert "commit1"
pick 16b8053 用 revert 做了修改
# Rebase 2d65e33..16b8053 onto 2d65e33 (3 commands)
#
输入“i”,进行编辑,把第2、3条的pick改为squash
pick 9194522 commit2
squash 4e1c7e4 Revert "commit1"
squash 16b8053 用 revert 做了修改
修改完成后在英文输入法下输入ESC : w q 回车退出编辑界面,然后看一下有没有冲突,有的话解决冲突,然后执行
git add .
(暂存)
git rebase --continue
(继续rebase)
这时会看到
Rebasing (3/3)
# This is a combination of 3 commits.
# This is the 1st commit message:
commit2
# This is the commit message #2:
Revert "commit1"
This reverts commit 2d65e33320fbd7129b2e7f7a3f88b7f9d985142f.
# This is the commit message #3:
用 revert 做了修改
此时可以修改所有的 commit message,作为合并后的commit message,然后 ESC :wq回车,到这里就完成了本地三个提交的合并。
然后执行
git push -f
(强制推送,完成远端的同步)
其他收录
在Mac、Linux 终端显示 Git 当前所在分支
mac终端启用tab补全
git "Could not read from remote repository.Please make sure you have the correct access rights."解决方案