Git是我们现在比较常用的版本管理系统,学会Git是我们每一位开发者的必备技能。
所以本篇我们主要来总结一下git的常用命令及使用的基本流程。
安装Git【比较简单,不多赘述】
要使用Git,第一步就是要先安装Git,安装完成后我们可以通过 git –version 来查看git的版本号;
git --version
因为Git是分布式版本控制系统,所以我们在安装完成后,需要设置一下提交代码时的用户信息
git config --global user.name '张佳丽'
git config --global user.email 'zhang.jiali@datatom.com'
注意 git config 命令的 –global 参数,用了这个参数,表示你这台机器上所有的 Git仓库 都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。
可以通过 git config –list 来查看当前的git配置
在工作过程中我们每天都会使用Git。一般来说日常使用只要记住6个左右就可以了,但是要熟练使用,差不多要记住60-100个命令
几个专用名词:
- Workspace:工作区
- Index / Stage:暂存区
- Repository:仓库区(本地仓库)
- Remote:远程仓库
下面重点介绍一下我们在项目开发过程中Git的一些常用命令及一些可能的问题,其他git相关的内容大家可以根据自己的情况再去近一步学习:
新建代码库:我们最常用的是git clone,将代码从代码仓库中克隆到本地;
<!-- 在当前目录新建一个git代码库 -->
git init
<!-- 新建一个目录,将它初始化为git代码库 -->
git init [project-name]
<!-- 从代码仓库中下载一个项目以及整个代码历史 -->
git clone [url]
git clone 有两种方式:
- HTTP
- SSH
新建分支:我们要求通过分支的方式来开发。比如每次开发新功能,修复bug等都应该新建一个单独的分支来开发
// 新建一个分支,并切换到该分支
git checkout -b feature-search
// 相当于
// 新建一个分支,但仍停留在当前分支
git branch feature-search
+
// 切换到指定分支,并更新工作区
git checkout feature-search
我们可以使用git branch来查看所有本地分支;(git branch -a查看所有本地分支和远程分支)
注意事项
// 新建一个分支,与指定的远程分支建立追踪关系
git branch --track [branch] [remote-branch]
// 建立追踪关系,在现有分支与指定的远程分支之间
git branch --set-upstream-to=origin/<remote-branch> branch
提交分支:代码修改后,就可以提交分支了,具体的步骤:
// 显示所有有变更的文件
git status
// 添加所有变更文件到暂存区
git add .
// 添加指定文件到暂存区
git add [file1] [file2] ……
// 将文件从暂存区移除
git reset HEAD [file1]
// 重置暂存区的指定文件,与上一次commit保持一致,但工作区不变
git reset [file]
// 重置暂存区与工作区,与上一次commit保持一致
git reset --hard
// 重置当前分支的指针为指定commit,同时重置暂存区,但工作区不变
git reset [commit]
// 提交暂存区到仓库区
git commit -m [message]
// 新建一个commit,用来撤销指定commit
// 后者的所有变化都将被前者抵消,并且应用到当前分支
git revert [commit]
与主干同步:分支的开发过程中,要经常与主干保持同步。
一旦远程主机的版本库有了更新(Git术语叫做commit),需要将这些更新取回本地,这时就要用到git fetch命令;
// 将某个远程主机的更新,全部取回本地。
git fetch <远程主机名>
// eg: git fetch origin
git merge origin/master
git rebase origin/master
git fetch命令通常用来查看其他人的进程,因为它取回的代码对你本地的开发代码没有影响。
默认情况下,git fetch取回所有分支(branch)的更新。如果只想取回特定分支的更新,可以指定分支名。
git fetch <远程主机名> <分支名>
// eg: 取回origin主机的master分支。
git fetch origin master
所取回的更新,在本地主机上要用”远程主机名/分支名”的形式读取。比如origin主机的master,就要用origin/master读取。
取回远程主机的更新以后,可以在它的基础上,使用git checkout命令创建一个新的分支。
// 在origin/master的基础上,创建一个新分支。
git checkout -b newBrach origin/master
也可以使用git merge命令或者git rebase命令,在本地分支上合并远程分支。
// 在当前分支上,合并origin/master
git merge origin/master
git rebase origin/master
可以使用 git rebase –abort 丢弃合并
在git merge或者git rebase之前可以先使用git diff 来查看变更;
git diff origin/master
合并commit:分支开发完成后,可能会有多个commit,但是合并到主干的时候,希望只有一个(或者最多两三个)commit,这样不仅清晰,也容易管理。
- 对于 commit 的修改可以使用 git commit -amend 修改下 commit 信息;
// 使用一次新的commit,替代上一次提交 // 如果代码没有任何新变化,则用来改写上一次commit的提交信息 git commit --amend -m [message]
-
那么怎样才能将多个commit 合并呢?这就要用到git rebase命令。
可以使用 git log –oneline / git log –graph –pretty=oneline –abbrev-commit 查看 commit 信息。
<!-- 如果想合并最近四次的提交: --> git rebase -i HEAD~4
git rebase命令的i参数表示互动(interactive),这时git会打开一个互动界面,进行下一步操作;
上面的互动界面,先列出当前分支最新的4个commit(越下面越新)。每个commit前面有一个操作命令,默认是pick,表示该行commit被选中,要进行rebase操作。
4个commit的下面是一大堆注释,列出可以使用的命令。
pick:正常选中 reword:选中,并且修改提交信息; edit:选中,rebase时会暂停,允许你修改这个commit(参考这里) squash:选中,会将当前commit与上一个commit合并 fixup:与squash相同,但不会保存当前commit的提交信息 ……
上面这6个命令当中,squash和fixup可以用来合并commit。先把需要合并的commit前面的动词,改成squash(或者s)。
- 把上图中第2,3行的动词改为s;
这样一改,执行后,当前分支只会剩下两个commit。第二行和第三行的commit,都会合并到第一行的commit。提交信息会同时包含,这三个commit的提交信息。
- 如果将第三行的squash命令改成fixup命令
运行结果相同,还是会生成两个commit,第二行和第三行的commit,都合并到第一行的commit。但是,新的提交信息里面,第三行commit的提交信息,会被注释掉。
使用git rebase合并多次commit信息有什么好处?
- 可以避免将错误的 commit 信息提交到代码仓库
- 比如这次的代码提交你需要合并到其他分支时,只需要cherry-pick 一次就可以,否次需要cherry-pick多次;而且时间长了容易遗忘【很难记得一个功能分为几次提交的】
- 使用 rebase 修改 commit 只在本地分支发生
- 本地分支 push 到服务器仓库上前都应该先 git rebase origin (branch) 保证拉取最新代码。
- 禁止使用 git push –force 覆盖服务器上的提交历史。
推送到远程仓库:合并commit后,就可以推送当前分支到远程仓库了。
// 正常的话使用
git push
// 如果使用了git rebase可能需要强制推
// 需要谨慎使用
git push --force
git push --force origin test
// git push命令要加上force参数,因为rebase以后,分支历史改变了,跟远程分支不一定兼容,有可能要强行推送。
// 如果远程仓库没有这条分支的话,需要用以下命令来推
git push --set-upstream origin test
git push -u origin test
Merge Request 流程
提交到远程仓库以后,就可以发出 Pull Request 到master分支,然后请求别人进行代码review,确认可以合并到master。
常见问题:
1.git clone 有时会遇到问题:fatal: unable to access
解决办法
- 通过ssh方式链接远程仓库获取代码——创建ssh key $ ssh-keygen -t rsa -C “your email address” – 填写gitLab邮箱 连续按按三个Enter ,ssh key创建成功 注意:生成id_rsa这是私钥文件。id_rsa.pub这是公钥文件。
- 将公钥添加到gitLab账户的key中即可。
- 根据git的ssh链接地址clone
2.可能需要同时处理多项任务,比如:在feature-search分支开发新功能的途中,有一个紧急bug需要在两个小时内修复完成,而新功能可能还需要1天或者更长的时间,没有办法立马提交。这个时候怎么办?
可以使用git stash把当前工作现场“储藏”起来,等以后恢复现场后继续工作:
我们开发新功能或者修复bug都是需要新开一条分支的! 解决办法
- 使用 git stash 将feature-search开发到一半的代码暂存一下;
- 然后用git status查看工作区,就是干净的(除非有没有被Git管理的文件),因此可以放心地创建分支来修复bug。
- 接着确定要在哪个分支上修复bug,假定需要在master分支上修复,就从master创建临时分支:eg:bugfix-0705;
- 修复完bug后切回开发到一半的分支继续开发,可以使用git status查看工作区,确保工作区是干净的。接着用git stash list命令查看;
- 可以通过两种方式来恢复:
- 是用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除;
- 用git stash pop,恢复的同时把stash内容也删了:
- 可以多次stash,恢复的时候,先用git stash list查看,然后恢复指定的stash,用命令:git stash apply stash@{0}
3.在master上修复了bug后,我们要想一想,这个bug其实在多条分支上都是存在的。是否需要重复修复、重复提交?
我们只需要将指定的提交合并过来,而不是整条代码线;
解决办法
可以用git cherry-pick
注意 这两个commit只是改动相同,但是是两个不同的commit。根据commit ID可以看出;
4.git commit 的提交信息
feat: 新功能(feature)
fix: 修补bug
docs: 文档(documentation)
style: 格式(不影响代码运行的变动,比如格式化了代码、if-else优化)
refactor: 重构(即不是新增功能,也不是修改bug的代码变动)
test: 增加测试
chore: 构建过程或辅助工具的变动
5.git pull
使用git pull时建议使用git pull --rebase
git pull --rebase
6.要利用好git status和git log
在项目开发的过程中要随时使用git status和git log;
- 要随时掌握工作区的状态,使用git status命令。
- 如果git status告诉你有文件被修改过,用git diff可以查看修改内容。