1. 本地新建仓库
git init
在已有仓库中执行git init
是安全的,它不会覆盖已经存在的东西。重新运行git init
的主要原因是拾取新添加的模板。
2. 克隆远程仓库
git clone <url> [<local_path>] [--recurse-submodules] [--jobs=<n>]
-
<url>
远程仓库的地址 -
<local_path>
本地仓库的存储目录。可缺省,缺省值为当前目录 -
--recurse-submodules
递归拉取子仓库 -
--jobs=<n>
多任务同时进行,以加快速度。<n>
表示任务数
例:git clone ssh://pythonSDK.public@192.168.23.98:39418/pythonSDK --recurse-submodules --jobs=12
3. 查看子仓库列表
git submodule
进入到PythonSDK目录,执行结果如下:
f1a6efe6f3e1689d85b24b224eea1637c8b55389 components/ZBar (heads/master)
738e7680562ed1f1cfadd9bbd68c3a77ef2ec144 components/jpeg (738e768)
9384e7da139f6b89d8d07fe8a1ef7346dba1d27a components/lvgl (heads/master)
523fd7aa21880623b024fb5f2161347b6366c982 components/quecsdk (heads/master)
b801932b8ed33b3981f031d5709f7d23fc2933c0 components/rtmpdump (b801932)
ec9910552961feb7f2e8f3c11aa7cbcfb8b52479 services/microPython (ec99105)
b5db751efbcbf509ff96b392399676e36d7e21c2 system/mbedtls (heads/master)
4. 遍历所有子仓库,并切换到master分支
git submodule foreach git checkout master
该命令用来遍历所有子仓库,并逐个切换到master分支。
命令模板:git submodule foreach <git_cmd>
git submodule foreach
命令用来对所有子仓库做统一的操作。
-
<git_cmd>
对子仓库执行的git命令
例:git submodule foreach git status
5. 查看仓库的状态
git status
该命令用于列出当前仓库的状态。
- 干净的工作区:
- 已修改文件,但未加入到暂存区
- 已加入到暂存区,但是未提交到本地仓库
- 新增的、未被git仓库跟踪管理到的文件
6. 查看提交日志
git log [--name-only | --name-status]
-
<--name-only>
日志中按行显示被修改的文件名称列表 -
<--name-status>
日志按行中显示被修改的文件名称列表,且每行的开头显示文件的修改状态。A file1
新增file1文件D file2
删除file2文件M file3
修改file3文件Rxxx file4 file5
file4文件重命名为file5,其中xxx是一个百分比,表示新旧文件名对应的文件内容的相似度,比如R100 file4 file5
,file4和file5的相似度位100%,即完全一样,说明file5确实是file4重命名而来的。
git如何得知新文件是旧文件重命名而来的?
当前检测到旧路径的文件被删除,而增加了新路径的文件,根据两个文件的相似度判断是否可归结为重命名,并记录相似度。
这里提及到旧路径的文件和新路径的文件,git判断是否未重名为时,不仅是在相同目录下的两个文件,只要是绝对路径不同的两个文件,都可以被git判断是否位重命名。比如
R90 path1/file4 path2/file5
,文件path1/file4重命名为path2/file5,相似度为90%(可能因为修改了文件内容)。
7. 将待提交文件添加到暂存区
git add <file...> [-f]
git add <dir...> [-f]
git add -A [-f]
git add -u [-f]
-
<file...>
待添加的文件列表,支持通配符 -
<dir...>
待添加的文件夹列表,支持通配符,git add .
添加所有修改的和新建的文件到暂存区 -
-A
添加所有被删除、被替换、被修改和新增的文件到暂存区 -
-u
添加所有被删除和修改的文件到暂存区 -
-f
添加被忽略的文件 - 其它众多的选项
git add
后跟上目录参数时,如果有通配符,则将符合通配符的文件添加进来;否则会将所有文件(包括untracked files)添加进来,很有可能会添加不想提交的文件。
所以git add
前先使用git status
查看一下当前的修改状态,最好再使用git diff
命令check下每个文件的修改是否正确。
git add
命令执行完后,如果再次修改了其中的文件,需要再次将修改的文件添加进暂存区,否则,本次的修改不会被提交。
8. 从暂存区撤销误添加的文件
git reset <file...>
git reset <dir...>
-
<file...>
待撤销的文件列表,支持通配符 -
<dir...>
待撤销的文件夹列表,支持通配符
例:git reset Makefile
该命令撤销了加入到暂存区的Makefile文件,但是文件的内容仍保持之前修改后的状态。
9. 撤销未加入暂存区的文件的修改
git checkout -- <file...>
git checkout -- <dir...>
-
<file...>
待撤销的文件列表,支持通配符 -
<dir...>
待撤销的文件夹列表,支持通配符
例:git checkout -- Makefile
10. 隐藏和恢复不想提交的文件的修改
git stash [save [<msg>]] [--all | --include-untracked] [<file...> | <dir...>]
该命令会将已加入暂存区、未加入暂存区的所有已跟踪文件,甚至未跟踪文件的修改隐藏。
-
save
表示执行隐藏的动作。可缺省,缺省后,不可携带用户追加的消息。 -
<msg>
用户追加的消息字符串,建议加上消息,便于追踪。 -
--all
隐藏包含未跟踪文件在内的所有文件。 -
--include-untracked
隐藏包含未跟踪文件在内的文件。隐藏已跟踪的哪些文件,由[<file...> | <dir...>]
决定,可以为空,同--all
。
在已有未恢复的隐藏情况下,可多次执行该命令,继续隐藏修改点,类似于数据的入栈。
git stash list
该命令会按行列出所有隐藏修改的记录。第一行为最近隐藏的修改。
格式:stash@{<n>}: <msg>
-
<n>
按照隐藏的时间顺序倒序编号,最近一次的编号为0。
git stash pop [<n>]
-
pop
恢复隐藏的修改。 -
<n>
恢复指定编号的隐藏修改,最近一次的编号为0。可缺省,缺省时表示恢复当前编号为0的隐藏。
由于操作稍微复杂,培训时再做演示。
11. 提交代码
git commit [-a] [-m <msg>] [--amend]
-
-a
自动将未加入暂存区的已跟踪文件加入暂存区。可缺省,缺省后只提交已经使用git add
加入暂存区的修改。 -
-m
后面跟上提交日志。可缺省,缺省后git会弹出编辑器让用户编写提交日志。 -
<msg>
提交日志。 -
--amend
重写最近一次提交的日志。
12. 推送至远程仓库
git push [<remote> <local_branch>:<remote_branch>] [-u] [-f]
-
<remote>
远程仓库的别名,由git remote add
设定,git clone
拉取的仓库,该值为origin
,可修改。 -
<local_branch>
本地分支名 -
<remote_branch>
远程分支名 -
-u
关联远程分支,用于将自己创建的本地仓库推送到远程仓库。第一次推送时,加上-u
,便会将本地仓库和远程仓库关联起来,后续可不用带’-u’。本地仓库和远程仓库不关联,是推送成功的。git clone
拉取的仓库,本地仓库已经和远程仓库做了关联,可直接提交。 -
-f
强制推送当前的仓库到远程仓库,用以覆盖远程仓库的文件。该选项请勿轻易使用,即使有code review机制。
有code review机制的远程仓库,向其推送修改时,远程分支名为refs/for/<branch>
。<branch>
为具体的远程分支名,如master、dev等。
例:git push origin HEAD:refs/for/master
将本地HEAD
指向分支的修改推送到远程的master分支。HEAD
指向当前工作区最新的提交。
13. 拉取远程代码,但是不合入本地
git fetch
需要使用git merge
命令合入
14. 代码合并
git merge [<branch> | <commit>]
-
<branch>
源分支名,可以是远程或本地的分支 -
<commit>
提交的id
git fetch
后,跟着git merge
,可实现拉取远程代码合入本地
15. 拉取远程代码合入本地
git pull
等于git fetch
+ git merge
。
该方式使用较多;也可根据需要选择使用git fetch
,而后在必要的时候git merge
。
git pull --rebase
= git fetch
+ git rebase
将远程代码合入到本地,但是和本地代码产生冲突时,不会向单纯地使用git pull
(即git fetch
+ git merge
)一样,产生合并的分叉线(参考19节git rebase
命令)。
16. 分支创建和删除
-
创建分支
git checkout -b <branch> [<commit>]
git branch <branch> [<commit>]
-
<branch>
新分支名。 -
<commit>
基于该commit-id创建新分支,可缺省,缺省后基于当前的HEAD创建新分支。 -
git checkout -b
创建新分支并切换过去。 -
git branch
仅创建新的分支,不切换过去。
-
-
删除分支
git branch -d <branch>
-
<branch>
分支名。不可删除当前分支,需切换到另一个分支,来删除目标分支。
-
17. 标签
-
添加标签
git tag <tag>
-
<tag>
标签名。
-
-
添加带说明的标签
git tag -a [-m <msg>] <tag>
-
-a
表示要添加标签。 -
-m
表示要添加说明信息。 -
<msg>
添加的说明信息。如果不携带-m
,不需要此项,但是git会打开默认编辑器,让用户添加说明信息。 -
<tag>
标签名。
-
-
列出标签
git tag [-l [<match>]]
-
-l
按照通配符模式列出相关的标签。例:git tag -l v1.*
,表示列出所有v1.x的标签。
该项可省略,变成git tag
,表示列出所有标签。 -
<match>
标签的通配符模式。
该项可省略,变成git tag -l
,也表示列出所有标签。
-
-
显示指定标签的修改内容
git show <tag>
-
<tag>
标签名。
-
-
查看所有的远程标签及commit-id
git ls-remote --tags origin
-
推送指定标签到远程仓库
git push origin <tag>
-
<tag>
标签名。
-
-
推送所有标签到远程仓库
git push --tags
-
删除远程仓库的指定标签
git push --delete origin <tag>
-
<tag>
标签名。
该命令仅会删除远程仓库的标签,本地的标签依然存在,下次执行git push --tags
时依然会推送到远程。
可根据需要,调用git tag -d <tag>
命令来删除本地标签。
-
-
删除本地仓库的指定标签
git tag -d <tag>
-
<tag>
标签名。
-
18. 回退代码
-
以干净的状态,将HEAD回退到指定的commit-id
git reset --hard <commit>
-
<commit>
指定回退的commit-id。
该命令执行后,git log
查询到的最新的commit-id为<commit>
的值。
工作区的状态:干净的,没有任何未提交的修改。
-
-
以脏的状态,将HEAD回退到指定的commit-id
git reset --mixed <commit>
-
<commit>
指定回退的commit-id。
该命令执行后,git log
查询到的最新的commit-id为<commit>
的值。
工作区的状态:脏的,在当前提交的基础上做的修改未加入暂存区。
-
-
以加入暂存区的状态,将HEAD回退到指定的commit-id
git reset --soft <commit>
-
<commit>
指定回退的commit-id。
该命令执行后,git log
查询到的最新的commit-id为<commit>
的值。
工作区的状态:在当前提交的基础上做的修改加入了暂存区。
-
19. 变基
-
将多次提交合并为一个,或将提交历史的merge分叉变直
git rebase -i <start_commit> <end_commit>
-
<start_commit>
开始的commit-id,不包含该commit-id -
<end_commit>
结束的commit-id,包含该commit-id
根据弹出的窗口的提示,填写对应的指令,决定是将多个提交合并为一条,还是做其他的操作。
-
-
将某一段提交合并到另一个分支
git rebase <start_commit> <end_commit> --onto <branch>
-
<start_commit>
开始的commit-id,不包含该commit-id -
<end_commit>
结束的commit-id,包含该commit-id -
<branch>
目标分支
-
-
合并两个分支
git rebase <branch>
-
<branch>
将分支branch合并到当前分支。
执行该命令时,会先将当前分支的提交全部取消,并作为patch临时放入.git/rebase目录下。
接着,会将分支branch的代码合并到当前分支。
最后,将临时的patch合入到当前分支。
-
git rebase
命令的使用,应遵循以下原则:
git rebase
while(存在冲突) {
git status
找到当前冲突文件,编辑解决冲突
git add -u
git rebase --continue
if( git rebase --abort )
break;
}
git merge
命令在合入代码时,会在基线上产生merge的分叉效果,有些人会觉得很混乱。
使用git rebase
命令可避免该现象,并且还可将历史merge的分叉线变直。