Git 常用操作
git clone
1 | git clone <repo-url> |
示例命令如下
1 | git clone https://github.com/boostorg/boost.git |
一些常用的参数(全部参数选项可以通过 git clone --help
查看)
--recursive
或--recurse-submodules
(在较新版本的 git 中使用,命令的语义更加清晰):当要拉取的仓库中包含 submodule 时,是默认不会拉取子仓库的,而指定这个参数即可拉取所有的子仓库。如果我们在下载的时候忘记指定
--recursive
,也可以通过下面命令重新拉取子仓库1
git submodule update --init --recursive
--depth
:当我们只想下载指定更新次数的分支(这样可以减少下载的大小,在我们只需要最新的提交记录时很有用,当然也可以直接下载 zip 或 tar.gz 等压缩文件来解决。-b
或者--branch
:指定要拉取的分支名称,例如下载 boost-1.86.0 (这个实际上是一个 tag,但也可以通过这种方式下载)。1
git clone https://github.com/boostorg/boost.git --branch boost-1.86.0
添加 SSH 密钥
创建 ssh 密钥对,通过
ssh-keygen
创建即可1
ssh-keygen -t <加密方式> -C <密钥注释>
示例如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21PS D:\Code\Git> ssh-keygen -t ed25519 -C "foo@example.com"
Generating public/private ed25519 key pair.
Enter file in which to save the key (C:\Users\xiao/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in C:\Users\xiao/.ssh/id_ed25519.
Your public key has been saved in C:\Users\xiao/.ssh/id_ed25519.pub.
The key fingerprint is:
SHA256:rJ2ufXZ93fAPNsdqBrdUsMSABhse7zBpo0ewRa3nn+s foo@example.com
The key's randomart image is:
+--[ED25519 256]--+
| ..*o ..o |
| = *+ + |
| . Xo. . o |
| =.=. . .|
| . So. . |
| + .. . +. |
| . o . *++=|
| o o +.===|
| ..oo oE+..o|
+----[SHA256]-----+会提示我们创建的密钥对已经放置在了
C:\Users\xiao\.ssh
路径下更新 ssh 的配置,修改
~/.ssh/config
,添加如下内容1
2
3
4Host gitlab.com
HostName gitlab.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/gitlab.private-key.pem在 gitlab 或者 github 上添加 SSH 密钥
进入用户设置,点击
SSH Keys
点击 Add new key
将刚才创建的密钥对中公钥部分添加到此处,然后点击 Add 即可添加 SSH 密钥
测试连接,在命令行中输入如下命令
1
2
3
4PS D:\Code\Git> ssh git@gitlab.com
PTY allocation request failed on channel 0
Welcome to GitLab, @PureWhiteVK!
Connection to gitlab.com closed.如果有类似输出,则说明 SSH 密钥添加成功
通过 SSH 方式下载源码
复制 Clone with SSH 中给出命令,在命令行中执行即可拉取源码
git branch
创建
直接使用 git checkout
创建分支,示例如下
1 | git checkout -b bugfix/my-bugfix-branch |
(这个实际上等价于下面的两条命令)
1 | git branch -f bugfix/my-bugfix-branch |
因此使用 git checkout -b <branch>
是最常用也最典型的操作方式
删除
通过下面命令删除分支
1 | git branch -D <branch-name> |
如果要删除远端分支(不推荐),需要通过 git push
命令完成,示例如下
1 | git push origin --delete <branch-name> |
重命名
通过下面命令重命名分支(实际上是移动或者拷贝,这两种方式都可以实现重命名效果)
1 | git branch -m <old-branch> <new-branch> |
此处的 -m
表示 move,和 Linux 上 move
命令一致,就是移动分支到新的标识符下。
也可以使用 -c
,其表示 copy,和 Linux 上 cp
命令一致,其好处就是不会丢弃原有的分支
合并
在 git 中有两种方式可以实现合并,merge 和 rebase,下面简单描述下二者区别:
merge:创建一条新的 commit,将分支1的改动和分支2的改动合并,记录在此 commit 中
优点是能完整的记录所有的改动历史
缺点是主干的历史并不是完全线性的,在版本回退时不太方便(通过 github 的 PR 或者 gitlab 的 MR 都可以确保主干线性历史)
rebase:将分支1中的相对于分支2不同的 commit 在 分支2 上重新提交一遍,不会创建新的 commit,但是分支1中改动部分的 commit 的哈希值会发生改变(因为相当于在分支2上重新做了一遍)
优点是能保证改动历史完全线性
缺点是记录的历史实际上是改动过的(因为哈希值发生变化)
对于这一部分的介绍推荐使用 Learn Git
Branching 网站通过图形化方式加深对 git merge
和
git rebase
的理解。
拉取
git fetch
通过 git clone
下载到本地的分支,实际上git
会帮我们自动创建一个 origin/xxx
分支(可以通过
git branch -a
查看所有的分支),而 git fetch
做的就是将远端的更新同步到本地的 origin/xxx
分支中,如下所示
1 | PS D:\Code\Git\Learn-Git> git branch -a |
git pull
pull
想对于 fetch
的区别就是其默认会将远端分支 merge
到本地分支(如果远端分支和本地分支存在冲突的话),如果没有的话就直接
fast-forward 即可
本地强行同步远端分支
当远端分支进行过 rebase
操作后,可能会导致本地分支和远端分支不一致,如果直接使用
git pull
会将远端的操作和本地操作都保留(即出现了两次历史),我们可能想避免这种行为,可以通过以下操作进行同步
1 | git fetch |
通过 reset 命令本地分支强行重置到指定的分支上,这里我们指定的是
origin 的分支(即远端分支),并通过 --soft
确保本地尚未提交的改动还能继续保留
git push
这个命令没什么好说的,就一条
1 | git push |
如果本地创建了一个分支,想要将该分支也提交到远端的话,直接
git push
会出错,但是 git 也会给出解决方案
1 | PS D:\Code\Git\Learn-Git> git push |
我们只需要执行上面提到的命令即可
1 | git push --set-upstream origin new-branch |
当然,也可以通过改变 push 的默认行为来自动创建,不过这个设置就看个人了
强行推送远端分支
当远端分支和本地分支有区别的时候(例如本地进行了 rebase 或者 reset 操作,导致 git 的记录出现问题时),我们可能需要强制将本地分支覆盖掉远端分支,就可以通过下面命令进行
1 | git push -f |
一般这个命令仅在个人的分支使用(例如
bugfix/xxx
或feature/xxx
)
git stash
当我们本地分支有改动尚未提交(未通过 git add 和 git commit
时)但是需要切换分支时,git 会提示有改动未暂存,此时我们可以通过
git stash
命令暂存,其就使用起来就相当于一个栈,
入栈操作:就是将当前所有的改动暂存起来
1
git stash
出栈操作:就是将当前暂存的改动释放出来,应用到当前分支中
1
git stash pop
说明
上面介绍了一些常用的 git 命令,如果碰到其他的就直接使用
git <command> --help
查看相关文档,或者直接百度即可。