这篇文章系统性的总结下 git 常见命令的使用方法。
- 背景需求
今年以来帮助实验室的博士生做了两篇论文的实验。做 paper 的实验有一个特点:需求会经常变动,经常是这种方法效果不行,那就需要换另外一种方法进行试验。导致的结果就是代码会经常变动,并且这次改动之后以后还有可能需要改动回来,因为一直没有用上 git,所以就显得代码非常混乱。最后非常尴尬的局面就是:今天需要尝试下这个方法能不能 work,需要将整个项目的代码过一遍,保证当前的代码、当前需要执行的程序、当前的参数是和这个需求符合的;明天可能又换了一种方法;后来又需要重新切换会第一天的方法,又得整个把代码给过一遍,将一些注释给重新注释回来,反正就是非常非常麻烦,人工一遍一遍进行代码控制非常累。
但是在实验过程中间又不想去使用新的技术,即使使用 git 是一件非常直觉的事情,知道 deadline 也没有用 git 来管理项目代码……
paper 投出去之后,就觉得将 git 使用熟练真的太太太重要了。
- 常见命令使用方法
创建一个 git 仓库
手下,我们可以在 github 上面找到任意一个 repository,在本地 git clone 下来(注意,不是下载 github 上面的 .zip 压缩包),那么这个项目对应的文件夹本身就是一个 git repository。
如果我们从零开始创建 git 仓库,也很简单,先新建一个文件夹,进入文件夹,然后:
git init
就会在当前文件夹下面生成 .git 文件夹,默认是不可见的。这个 .git 就是用来存储我们对目录文件的所有操作历史的。
git add & git commit
这里首先需要解释下 git 的工作原理,如下图所示:
当我们使用 git add xxx.txt 命令时,当前对 xxx.txt 的修改将会被提交到 staging area;接着当我们继续使用 git commit -m “message” 时,这个修改才会被提交到 repository。
add 单个文件:
git add xxx.txt # xxx.txt 是文件名
add 多个文件
git add * # or git add .
git commit 时必须要带入提交信息(commit message):
git commit -m “your message about this commit”
git status & git diff
要查看当前 repository 的状态:
git status
如果要查看某个文件前后两次修改的差异:
git diff xxx.txt
git log & git reflog
查看我们 commit 的历史,可以:
git log
因为 git log 输出的信息很多,如果只想要简洁的输出,可以:
git log --pretty=oneline
假设我们现在有这样一串提交历史:
a1 -> a2 -> a3 -> a4 -> a5
我们从 a5 回退到 a3,这时候使用 git log 将只能查看到 a1 a2 a3 这 3 次的提交历史,a4 a5 的提交历史是查看不到的。这时候,如果我们改变主意,又想从 a3 回到 a5 该怎么办呢,就可以使用:
git reflog
可以查看所有的提交历史记录。我们只需要知道我们在 a5 时的 commit message 然后找到对应的 commit id,就可以回退到 a5。
下面具体讲怎么进行版本回退或者版本切换。
git reset
和之前一样,假如我们有下面这一串 commit 的历史,我们希望从 a5 回退到 a3。
a1 -> a2 -> a3 -> a4 -> a5
首先在 a5 我们输入 git log 查看 a3 对应的 commit id,是一段很长的字母数字序列,假设前 4 位是 ab42,并且在所有的 commit id 里面是唯一的(方便我们做简写)。
接着执行:
git reset --hard ab42 # commit id 不用写全,写明能够标识该 commit id 的前几位即可
我们还有更方便的方法,可以不用知道 commit id :
git reset --hard HEAD^^
其中 HEAD^^ 标识我们切换会上上一个版本。如果指向切换为上一个版本,也就是 a4,那可以:
git reset --hard HEAD^