Git操作指南

Git 操作指令

0. Git 是什么


Git 是一个先进便捷的分布式版本控制系统。它可以实现对纯文本文件(code、txt、csv、md…)的修改提示(具体到某行)、回退到之前的版本、创建不同分支等等操作,这些操作都是可协作的。

1. 创建本地仓库(预备)


打开Git Bash命令行窗口,然后配置一下自己的名字和邮箱(自报家门),方便协作者看到是谁修改提交了版本,配置之后全局有效,你在当前电脑上的每个Git仓库都是使用这个配置。

1
2
$ git config --global user.name "jasonyang"
$ git config --global user.email "jayheyang@gmail.com"
  1. 切换到想要建立仓库的文件目录。
1
$ cd /h/code
  1. 在当前目录创建新的文件夹learngit, 然后切换到learngit目录。
1
2
$ mkdir learngit
$ cd learngit

可使用pwd指令查看当前目录

1
2
$ pwd
out-> /h/code/learngit
  1. 使用git init命令使得该目录变成可以被Git管理的仓库(文件夹)。
1
$ git init

2. 将文件添加到仓库


  1. 编写文本文件,可以是.py.md.txt等, 编写readme.txt,并保存到当前Git目录。
1
2
3
# readme.txt
Git is a version control system.
balabala...
  1. 把文件添加到Git的暂存区。
1
$ git add readme.txt
  1. 把所有暂存区的文件提交到Git仓库。
1
$ git commit -m "wrote a readme file"

-m指令表示对本次提交的文件添加一个说明。

3. 常用指令


3.1 基础储备


  • basic command
1
2
3
$ git init 
$ git add test.py
$ git commit -m "modified XXXX"
  1. 查看当前仓库状态,了解是否有些文件被删改。
1
$ git status
  1. 查看当前工作区文件与版本库文件有什么不同。
1
2
$ git diff readme.txt # readme.txt与当前版本库里readme.txt的不同
$ git diff HEAD^ -- readme.txt # readme.txt与上一个版本(上一次提交)里的readme.txt的异同。

找到不同之后可以根据情况使用git addgit commit添加并提交文件,或者使用git reset回退到修改前的版本。

  1. 查看提交的版本日志,包括分支(如果有的话)。
1
2
3
4
5
$ git log
or
$ git log --pretty=oneline

$ git log --graph # 可以看到分支的合并流程图

--pretty=oneline可以让返回的日志信息更加简略。

  1. 版本回退(针对已经进行git add 甚至git commit操作的情况)。
1
2
3
4
5
6
7
8
9
10
$ git reset # 移除仓库暂存区的修改,但不改变工作区文件,相当于撤销git add操作。
$ git reset <commit id> # 将仓库分支回退到指定<commit id>版本, 其余同上。
$ git reset --hard # 清除暂存区和工作区的改动。会强制修改工作区文件。
$ git reset --hard <commit id> # 将仓库分支回退到指定<commit id>版本, 其余同上。

$ git reset --hard HEAD^ # 回退到当前版本的上一个版本
$ git reset --hard HEAD~1 # 回退到当前版本的上一个版本

$ git reset --hard HEAD^^ # 回退到当前版本的上两个版本
$ git reset --hard HEAD~2 # 回退到当前版本的上两个版本。

<commit id>可以不用写全,类似1098abd这种前面几位就可以了。

没有加--hard的命令手动打开本地工作区文件例如readme.txt不会看到修改的内容撤销了,加了--hard的命令则会看到文件的内容回到了修改之前。

  1. 撤销修改(针对还未将修改文件提交到暂存区或者仓库的情况)。
1
$ git checkout -- readme.txt

撤销工作区里readme.txt文件最近的一次修改,如果文件提交到暂存区,则需要采用第4点的git reset操作进行回退。

注意:如果不小心将工作区文件rm删除了,也可以使用git checkout -- <file name>进行误删恢复, checkout指令就是保证工作区和版本库的文件一致。

  1. 彻底删除文件

    1. 删除工作区文件
    1
    $ rm test.py
    1. 删除版本仓库文件
    1
    $ git rm test.py
    1. 向Git仓库报告本次删除操作
    1
    $ git commit -m "remove test.py"
  2. 为每次提交打标签

    1. 为最近一次提交打标签
    1
    2
    $ git tag v1.0 # 为当前提交commit->HEAD打上v1.0的标签
    $ git tag -a v1.0 -m "version 1.0 released" # 打标签同时,提供标签说明
    1. 为指定commit id打标签
    1
    2
    $ git tag v0.9 f64c633 
    $ git tag -a v1.0 -m "version 1.0 released" f64c633
    1. 查看标签
    1
    2
    $ git tag # 查看已打的标签
    $ git show v1.0 # 详细查看v1.0本次提交操作
    1. 删除标签
    1
    $ git tag -d v1.0
    1. 推送标签到远程、删除远程标签
    1
    2
    $ git push origin v1.0 # 推送v1.0标签到远程`origin`分支
    $ git push origin --tags # 一次性推送所有标签
    1
    2
    $ git tag -d v1.0 # 先删除本地标签
    $ git push origin :refs/tags/v1.0 # 用'push'删除远程

3. 分支管理


分支是Git里面关键的功能,其能够实现平行化版本时间线,也能合并不同分支时间线的版本。
推荐创建以下分支:

  • master 默认创建的分支,负责更迭正式版本。
  • dev 协作分支,团队成员之间相互协作,测试版本更迭情况将在此分支的时间线上体现。
  • bug bug分支,一般只在本地库,用于修改程序bug。
  • feature 记录更迭自己本地更改的版本。

团队协作的Git版本库分支示意图(图源廖雪峰官方网站):

  1. 创建、查看分支
1
2
3
4
5
$ git checkout -b dev # 创建并切换到dev分支
$ git switch -c dec # 创建并切换到dev分支

$ git checkout master # 切换到master分支
$ git switch master # 切换到master分支

switchcheckout都可实现分支的创建与切换,老版本的Git使用checkout进行分支管理和文件恢复,现在分别由switchrestore管理。

1
$ git branch # 查看当前版本库所有的分支

各个分支之前管理的版本文件相互独立,修改一个分支的版本文件不会影响另一个分支。

  1. 合并、删除分支

合并分支

1
$ git merge dev # 将dev分支合并到当前分支

单独调用git merge命令时会采用Fast-Forward合并模式,合并完成之后会将分支dev时间上的commit混合到分支master的时间线上去,此时如果实行版本回退则会回退到dev分支所提交的内容,而不是目标master分支上的内容。

上述问题的解决办法就是使用git merge --no-ff指令:

1
$ git merge --no-ff -m "merge with no fast-forward" dev

该指令可以保留dev分支的提交信息,在分支master上进行版本回退时,可以正确退回master分支上的上一个版本,而不是dev分支上的上一个版本。

no-ff合并操作包含了一次git commit,因此-m参数是为了加上提交说明。

合并分支时,如果当前分支和被合并的分支都在上一个版本基础上进行了修改,合并会失败。同时发生合并冲突的文件例如readme.txt会自动添加内容告诉我们发生冲突的地方,此时需要手动修改冲突的文件。

readme.txt冲突发生后,打开文件可看到如下提示:

1
2
3
4
5
6
7
Git is a version control system.
balabala...
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> dev

然后需要手动修改readme.txt文件为:

1
2
3
Git is a version control system.
balabala...
Creating a new branch is quick and simple.

之后再执行git addgit commit -m提交到版本仓库,手动解决合并冲突。

删除分支

1
$ git branch -d dev # 删除dev分支

如果分支未合并,使用上面的删除指令会报错,这时需要使用下面的指令:

1
$ git branch -D dev # 删除dev分支
  1. 暂存工作区的任务

当遇到正在写的任务没写完,又发现了一个紧急任务时,需要当前任务先暂存起来,先处理紧急任务,处理完成之后再回到当前的任务中来。Git提供了解决方案:git stash

  1. 存储当前的任务(假设在dev分支)
1
$ git stash
  1. 去到紧急任务的分支,处理紧急任务
1
2
3
$ git switch master
$ git XXX
....
  1. 回到之前任务分支,恢复任务
1
2
3
4
$ git switch dev
$ git stash list # 查看被暂存的所有任务列表
$ git stash pop # 恢复最近的一个暂存任务
$ git stash pop stash@{0} # 恢复暂存的标号0任务,标号从list的输出信息中得到

4. 远程仓库操作


  1. 预备工作

第1步:创建私钥和公钥:打开Git Bash命令行窗口,输入下列指令:

1
$ ssh-keygen -t rsa -C "jayheyang@gmail.com"?

地址记得改成自己的email!!!

创建完成之后会在用户目录下(例如/c/Users/Administrator)找到.ssh文件夹,里面会有两个文件id_rsaid_rsa.pub

第2步:打开GitHub,登陆。然后依次点击:用户头像->Settings->左侧边栏的SSH and GPG keys->New SSH key

第3步:打开id_rsa.pub文件,ctrl A全选,ctrl C复制, 切换到GitHub页面,Title栏随便写,相当于给你的这个密钥起名字。然后在Key栏中粘贴刚才复制的文本。

预备工作完成。

  1. 关联本地仓库与远程仓库

    • 在GitHub上创建repository
    • 进入创建的repo,获取SSH链接(形如git@github.com:JayHeYang/learngit.git),打开Git Bash并切换到Git版本库目录,然后输入以下指令关联。
    1
    $ git remote add origin git@github.com:JayHeYang/learngit.git

    origin是默认的远程仓库名,可自行修改。

  2. 将本地仓库文件push上去

1
$ git push -u origin master

-u的作用是将本地master分支和远程master分支关联起来,后面只需要进行$ git push origin master指令即可。

1
2
$ git push origin master # push到远程端的master分支
$ git push origin dev # push到远程端的dev分支
  1. 查看所关联的远程库,或者删除与远程库的关联
1
2
$ git remote -v # 查看当前本地仓库关联的远程库
$ git remote rm origin # 解除与远程库origin的关联

git remote rm指令只是完成了解绑,如果要删除远程库中的文件还得在GitHub上修改。

  1. 从远程仓库克隆文件

    1.切换到需要存储克隆文件的目录:

    1
    2
    $ mkdir clonetest
    $ cd clonetest
    1. 获取需要克隆仓库的SSH连接(形如git@github.com:JayHeYang/learngit.git)执行clone指令。
    1
    $ git clone git@github.com:JayHeYang/learngit.git

    克隆完成。

如果是其他协作人从远程仓库clone时默认只能看到master分支,如果想要在dev分支上做开发,需要创建远程origindev分支到本地,用以下命令行:

1
2
3
$ git checkout -d dev origin/dev 
或者
$ git switch -c dev origin/dev

5.抓取分支并push上去

多人协作的流程是:
第1步:按照任务要求在本地分支上完成修改。
第2步:从远程仓库抓取分支,在本地合并,解决冲突。
第3步:将本地分支push到远程分支上,更新进度。

遵循以下命令顺序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ git switch dev # 切换到工作分支
或者
$ git checkout -d dev origin/dev # 将远程`origin`的`dev`分支创建到本地

$ git branch --set-upstream-to=origin/dev dev # 将本地分支与远程分支绑定

$ git pull # 抓取远程dev分支(抓取完成之后会自动进行合并)
$ git pull origin master # 也可以直接指定分支抓取

手动解决合并冲突(如果有的话)

$ git add test.py # 添加解决冲突后的文件

$ git commit -m "fix bug"

$ git push origin dev # push到远程分支

2022年3月3日11:09:23 更新:


注意:在github创建repo时如果添加了readme.md或者LINCESE等文件则在push之前得用以下操作:

1
$ git pull origin main --allow-unrelated-histories # 使用这个指令,来把远程仓库和本地同步,消除两个文档间的差异,其实也就是把远端文件下载下来

为了回避种族歧视,现在创建repo默认将master更改为了main

Git速查表:

img

参考文献


廖雪峰的Git的教程:https://www.liaoxuefeng.com/wiki/896043488029600

Git快查表:https://liaoxuefeng.gitee.io/resource.liaoxuefeng.com/git/git-cheat-sheet.pdf

Post author: jasonyang
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally. 转载请注明出处。