一、Git 是什么?

Git 是一个版本控制系统(version control)。如下图,git 包含以下组成部分:

workspace:工作区(clone 或者原始内容)
Index/Stage:暂存区(有增删改查之后 add 到临时区)
Repository:本地仓库(保存了本地的增删改查记录)
Remote:远程仓库

本文将从修改、分支、远程仓库、标签操作等五个方面的常用命令进行总结。

二、修改

2.1 暂存修改

操作 bash
创建 stash git stash
查看 git stash list
删除 git stash drop stash@{}
应用但不会删除暂存 git stash apply stash@{}
还原上一个暂存并删除暂存 git stash pop

如果在工作的时候出现了临时需要解决的问题,而你又不希望提交,那么有个stash功能。

1
git stash

在暂存后工作区会回退到最近的一个 commit 的状态,以便开启新的分支;这种操作常常用于修复 bug, 通常会通过创建新的 bug 分支进行修复,然后合并,最后删除;

当手头的工作没有完成时,先把工作现场 git stash 以下,然后去修复 bug,修复后再 git stash pop, 回到工作现场。

2.2 撤销修改

2.2.1 当工作区还未提交到暂存区

此时即还未git add 到暂存区时,可以使用下面的来放弃工作区的修改。

1
git checkout -- filename.txt   #将filename.txt文件在工作区的改动放弃

命令中的--很重要,没有--,就变成了“切换到另一个分支”的命令.

2.2.2 当还未提交至仓库

即此时已经git add至工作暂存区,但是还没有被git commit,此时可以用下面语句:

1
2
git reset HEAD filename.txt #将暂存区的修改撤销(unstage),重新放回工作区;HEAD 表示最新版本,
git checkout -- filename.txt # 放弃工作区的修改

2.2.3 当已经提交到仓库

此时修改已经git commit到仓库中,需要版本回退:

1
git reset --hard xxxx #版本号
  • 这里的 --hard 表示强制回退,丢弃本地的修改。这个回退比较野蛮,该版本号之后的提交都将不可见。
  • --soft 数用于回退到某个版本,会存储版本回退的信息;
  • --mixed 默认。用于重置暂存区的文件与上一次的提交(commit)保持一致,工作区文件内容保持不变。(即上一节的内容)

2.2.4 撤销之前的某个提交

git revert撤销一个提交的同时会创建一个新的提交,这是一个安全的方法,因为它不会重写提交历史。 git reset 是把HEAD向后移动了一下,而git revert是 HEAD 继续前进,只是新的commit的内容和要revert的内容正好相反,能够抵消要被revert的内容。

2.2.5 合并 commit

如果存在多次无用的 commit,可以使用 rebase 来精简提交记录

1
git rebase -i HEAD~4 # 合并最近的 4 次提交记录

此时进入 vim 模式,修改之前提交的记录

此时要注意不要合并已经提交远程分支的记录,否则会报错
注意这是一个危险的操作。

三、分支操作

操作 bash
查看分支 git branch
查看本地和远程分支 git branch -a
在 target 分支上创建分支,没有则从当前分支创建 git branch <branch-name> <target-branch>
创建并切换分支 git checkout -b <branch-name>
合并某些分支到到当前分支 git merge <branch-name>
删除分支,只能删除参与合并的 git branch -d <branch-name>
强行删除 git branch -D <branch-name>
删除远程分支 git push origin:<remote-branch-name>

3.1创建/切换分支

1
2
3
4
5
6
# 创建新分支
git branch bug-fix
# 查看分支,-a查看本地和远程的分支,-r查看远程分支,-l或没有只查看本地
git branch -a
# 切换到刚刚创建的分支
git checkout bug-fix

同时上面步骤可以合并为

1
2
# 创建并切换到分支
git checkout -b bug-fix

3.2 合并分支

3.2.1 正常合并

如果修改一下本地文件之后在这个分支继续培育一个版本之后,怎么去合并到主分支呢?

1
2
3
4
5
6
7
8
git add .
git commit -m "some change"
# 切换到主分支
git checkout master
# 合并分支
git merge bug-fix
# 删除分支 (可选)
git branch -d bug-fix

3.2.2. 分支冲突

如果 master 分支和新的分支都各自培育了版本,那么自动合并通常会失败,发生冲突 conflict,此时需要打开文件解决冲突之后 commit一个版本以完成合并

1
2
git add *
git commit -m "branch merge"

3.2.3. 分支合并的模式

分支合并包含三种模式,如图:

  • fast-forward:默认。不会显示 feature,只保留单条分支记录。“快进方式”,删除分支会丢失分支信息,
  • --no-ff:指的是强行关闭fast-forward方式。可以保存之前的分支历史。能够更好的查看 merge历史,以及branch 状态
  • squash 是用来把一些不必要commit进行压缩,主分支需要额外的commit进行总结。

四、远程仓库操作

操作 bash
克隆 git clone <url>
添加远程仓库 git remote add <name> <url>
删除远程仓库 git remote rm <name>
拉取 git pull <remote-branch-name> <local-branch-name>
推送本地所有分支到远程 git push –all origin
推送到远程同名分支 git push origin <local-branch-name>
推送本地分支到远程 master git push origin <local-branch-name>:master
把当前本地分支推送并创建到远程 git push origin
检出远程分支 git checkout -b <new-local-branch-name> origin/<remote-branch-name>

总结: git push <远程主机名> <本地分支名>:<远程分支名>

4.1 各个分支与推送与否

  1. master,分支是主分支,因此要时刻与远程同步;
  2. dev, 分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;
  3. bug, 分支只用于在本地修复 bug,就没必要推到远程了;
  4. feature, 分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。

4.2 多人协作

多人协作的工作模式通常是这样:

  1. 首先,可以试图用git push origin <branch-name>推送自己的修改
  2. 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并。
  3. 如果合并有冲突,则解决冲突,并在本地提交(add -> commit)。
  4. 没有冲突或者解决掉冲突后,再用git push origin <branch-name>推送就能成功

五、标签操作

你达到一个重要的阶段,并希望永远记住那个特别的提交快照,你可以使用 git tag 给它打上标签。一般是某个重要的发布版本更新需要标签操作。

操作 bash
查看所有标签 git tag
新建标签 git tag <tagname>
新建并指定说明 git tag <tagname> -m <message>
查看标签说明 git show <tagname>
删除标签 git tag -d <tagname>
推送某个标签到远程 git push origin <tagname>
推送所有未推送到远程的本地标签 git push origin –tags
合并远程仓库的标签到本地 git pull origin –tags
删除远程标签 git push origin:refs/tags/<tagname>

注意:
如果要删除的远程分支的标签,应该先删除本地的标签tag,再按照上面的 push。

六、常用命令速查表