基本用法

Reference https://www.liaoxuefeng.com/

配置

Git 一共分为三个级别的配置 system、global、local,分别是系统级、用户级、当前仓库

1
2
3
4
# 查看配置文件
git config --system --list
git config --global --list
git config --local --list

在 global 中需要配置提交的用户名和 Email 地址,
这是由于 Git 是分布式版本控制系统,在提交的时候需要自报家门。

1
2
3
4
# 配置用户名
git config --global user.name "Your name"
# 配置Email地址
git config --global user.email "email@example.com"

上述是对本机上所有的仓库进行了配置,也可以单独对某个仓库进行配置。

创建版本库 (repository)

1
git init

将当前目录变成 Git 可以管理的仓库,(为了避免出现错误,目录中不要出现中文)
创建版本库之后,当前目录下会多一个.git 目录,这个 Git 用于跟踪管理版本库

将文件添加到版本库

将文件添加到版本库需要两步

1
2
3
4
5
6
7
8
9
#  将文件添加到仓库
1. git add
# 将文件提交到仓库,-m “message" 提交说明
2. git commit -m

# 查看结果
git status
# 查看修改内容
git diff <content>

版本回退

1
2
3
4
5
6
7
8
9
10
#  查看修改记录,用于查看提交历史
git log
git log --pretty=oneline

# 版本的退回
# Git内有HEAD指针指向不同的版本
git reset --hard HEAD^
git reset --hard <commit_id>
# 查看每次的命令,用于重返未来
git reflog

文件状态

Git 控制系统分为工作区和暂存区
工作区便是当前建立仓库的目录
.git 文件夹为 Git 的版本库,版本库又分为暂存区以及分支
每次使用git add 命令,表示将工作区文件添加到暂存区,而使用git commit 命令是将暂存区的文件的添加到版本控制的分支上。
所以我们可以多次使用git add命令将文件添加的暂存区,而使用git commit一次性将暂存区文件添加到分支上

管理修改

Git 作为版本控制工具,用于跟踪并管理文件的修改,并非文件使用git diff HEAD -- <filename>命令可以查看工作区和版本库里面的最新版本的区别

撤销修改

  1. 撤销工作区的修改
    git checkout -- <filename>,将工作区的修改全部撤销,这里有两种情况
  • 文件被修改后还没有提交到暂存区,那么,撤销修改就会和分支最新版本一模一样
  • 文件以及添加到暂存区,那么,撤销修改就是恢复到暂存区的状态
  1. 撤销暂存区的修改
    git reset HEAD <filename>,可以把暂存区的修改撤销掉,重新放回工作区,之后可以按照情况一撤销工作区的修改
  2. 撤销已提交到分支的修改,按照版本退回操作

删除文件

当已提交的文档在目录中被删除之后(rm <name>),这时候工作区和版本库就不一致了,git status会提醒改动
那么就有两种情况

  1. 确实要删除这个文件,使用git rm <name>从版本库中删除文件,并且git commit提交改动
  2. 误删文件,那么可以从版本库中恢复出原来的文件git checkout -- <name>

远程仓库

使用 github,实现本地仓库与远程仓库之间的连接

  1. 创建 SSH Key。 在 git bash 中输入ssh-keygen -t ras -C "email_address"
  2. 在 github 网站个人设置页面添加 SSH Key

添加远程库

  1. 在 github 网站创建相应的 repository
  2. 本地仓库下运行git remote add origin git@github.com:repository_address.git
  3. 将本地仓库下的文件推送到远程库上git push -u origin master,第一次推送master分支时,加上-u参数,Git 不但把本地的master分支内容推送到远程新的master分支,并且把本地master分支和远程的master分支关联起来,在以后的推送或者拉取时可以简化命令git push origin master
1
2
3
4
5
6
7
# 添加远程仓库,origin是远程仓库的名字,Git的默认叫法,可以换为其他
git remote add origin git@github.com:repsitory_address.git
# 本地仓库的推送
# 第一次
git push -u origin master
# 以后
git push origin master

从远程库克隆

1
git clone git@github.com:repository_address.git

分支管理

在 Git 中每一次提交所串联起来就是一条时间线,每条时间线都是一个分支,主分支即为master分支,HEAD并不是指向分支,而是指向master分支,而master分支指向提交,所以HEAD指向的就是当前分支。
一开始的时候,master分支是一条线,Git 用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点:
每次提交,master分支都会向前移动一步,这样,不断提交,master分支的线也越来越长

创建分支

当我们创建新的分支的时候,Git 会新建一个指针,指向master相同的提交,再把HEAD指向这个新的指针,这就表示当前位于新的分支上,之后的提交会在新的分支上移动,即新的指针移动,而master指向原来的提交位置不动。
在合并的时候也仅仅是master指针的移动,删除去原来的指针,不涉及工作区内容的改变。

1
2
3
4
5
6
7
8
9
# 创建一个新的dev分支,并切换到新的分支上
git checkout -b dev
# git checkout 命令加上 -b 参数表示创建并切换,相当于两条命令的合并
# 创建新的分支
git branch dev
# 切换到新的分支
git checkout dev
# 查看当前分支
git branch

git merge命令用于合并指定分支到当前分支
git branch -d dev用于删除 dev 分支

解决冲突

当两个分支上都有新的提交的时候,再进行合并便会产生冲突,这时候 Git 没有办法进行“快速合并”,只能试图把各自的修改合并起来,使用git status告诉我们冲突的文件,Git 会用<<<<<<<<<=======>>>>>>>>标记处不同分支的内容
使用git log --graph命令可以查看分支合并图

分支管理策略

合并分支时,如果可能,Git 会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用Fast forward模式,Git 就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。

1
2
3
4
5
6
7
# 创建新的分支
git checkout -b dev
# 进行一次修改之后创建新的提交
git add
git commit -m ''
# 合并dev分支,使用--no-ff参数,因为合并要创建新的commit,所以加上-m参数
git merge --no-ff -m "merge with no-ff" dev

Bug 分支

stash可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作
stash list查看工作区保存目录,恢复时有两种方式

  • git stash apply恢复后 stash 内容不删除,需要用git stash drop来删除
  • git stash pop恢复的同时删除 stash 内容
    当有多个 stash 内容的时候,先使用git stash list查看,然后恢复到指定的 stash,使用git stash apply stash@{0}命令

Feature 分支

在一个新的分支上开发某种功能,完成后再用于合并。

1
2
3
4
5
6
# 新建分支
git checkout -b <name>
# 删除分支
git checkout -d <name>
# 删除一个没有被合并过的分支,强制删除
git branch -D <name>

多人协作

当从远程仓库克隆的时候,Git 自动将本地master分支与远程master分支对应起来,远程仓库的默认名称是origin
查看远程库的信息用git remote或者使用git remote -v查看更加详细的信息

推送分支

将该分支上的所有本地提交推送到远程库,推送时要指定本地分支

1
2
3
4
# 推送master分支
git push origin master
# 推送dev分支
git push origin dev

抓取分支

抓取 github 上的仓库git clone git@github.com:<path>.git,在默认情况下只能看到本地的master分支,如果要在其他的分支(dev)上开发,就必须创建远程origindev分支到本地git checkout -b dev origin/dev

多人协作中解决冲突

当本地分支提交了修改,而远程分支也提交了修改,再由本地向远程提交的时候就会产生冲突。
所以,多人协作的工作模式通常是这样:

  1. 首先,可以试图用git push origin <branch-name>推送自己的修改;
  2. 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;
  3. 如果合并有冲突,则解决冲突,并在本地提交;
  4. 没有冲突或者解决掉冲突后,再用git push origin <branch-name>推送就能成功!
    如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to <branch-name>origin/<branch-name>

Rebase 操作

将本地未 push 的分叉提交历史整理成直线,在查看历史提交变化的时候更加容易。
git rebase

标签管理

将某次提交打上标签,便于查找

创建标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 查看分支
git branch
# 切换到响应分支
git checkout master
# 打上标签
git tag <name>
# 查看所有标签
git tag
# 为历史提交打标签
git tag <name> <commitid>
# 查看标签信息
git show <tagname>
# 带有说明信息的标签
git tag -a <tagname> -m 'message' <commitid>
# 查看说明文字
git show <tagname>

操作标签

1
2
3
4
5
6
7
8
9
10
11
12
13
# 删除标签
git tag -d <name>
# 创建的标签只储存在本地,不会自动推送到远程,所以,打错的标签可以在本地安全删除
# 将标签推送到远程
git push origin <tagname>
# 一次性将全部推送到远程的本地标签
git push origin --tags

# 删除远程标签
# 先从本地删除
git tag -d <tagname>
# 再从远程删除
git push origin :refs/tags/<tagname>

专项

git submodule

用于在仓库下添加引用或发布的子模块,会在目录下添加.submodule文件,里面记录了子目录的 path 和 url

  • 添加

    1
    git submodule add repository path
  • 克隆

    克隆带子模块的版本库git clone url path --recursive递归克隆带子模块的版本库

  • 删除

    删除.git/config.gitsubmodules里关于 submodule 相关部分,然后git rm --cached <local path>

git remote

  • 查看本地仓库、远程仓库以及追踪关系
    git branch -vv -a

  • 添加远程仓库
    git remote add <shortname> <url>
    将远程仓库<url>影射为本地仓库中对远程仓库的别名 <shortname>,git remote add只负责映射。

  • 推送
    git push <远程仓库名> <本地分支名>:<远程分支名>在日常使用时可以为

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 第一次push 使用 -u 建立上游分支
    git push -u <远程仓库名> <本地分支名>:<远程分支名>
    # 之后即可缺省使用
    git push
    # 缺省使用远程分支名,默认用当前分支填充远程分支
    git push <远程仓库名>
    # 缺省远程分支名,用本地分支名填充远程分支名
    git push <远程仓库名> <本地分支名>
    # 长选项--set-upstream,等价于-u
    git push --set-upstream <远程仓库名> <本地分支名>

    reference

Q&A

  1. 修改commit注释信息

    在提交了以后发现注释不合适需要修改的方法

    1. commit后没有push
    1
    git commit --amend

    01
    02

    修改第一行注释信息即可

    1. push到远程仓库
      将本地修改后的信息提交到 github,使用强制修改命令git push origin master --force
  2. 解决error:failed to push some refs to 'remote'

    出现原因:本地仓库与远程仓库不一致
    解决方法:将远程仓库同步到本地仓库

    1
    2
    git pull -- rebase origin master
    git push origin master

    git pull --rebase origin master的意思是把远程库中的更新合并到本地库中,–rebase的作用是取消掉本地库中 z 最新的commit,并把他们接到更新后的版本库之中。
    注意:在使用这条命令之前需要使暂存区内没有文件,即搜所有的修改已经提交到分支或者舍弃。
    图解:

    01

    git pull –rebase origin master意为先取消commit记录,并且把它们临时 保存为补丁(patch)(这些补丁放到”.git/rebase”目录中),之后同步远程库到本地,最后合并补丁到本地库之中。

    02

    本地库push到远程库

    03