专有名词
名称 | 解释 |
---|---|
workspace | 工作区 |
index(或stage) | 暂存区 |
repository | 仓库区(或本地仓库) |
remote | 远程仓库 |
新建代码库
命令 | 解释 |
---|---|
git init |
在当前目录新建一个git代码库 |
git init [project-name] |
新建一个目录,将其初始化为git代码库 |
git clone [url] |
下载一个项目到本地 |
配置
Git的设置文件为.gitconfig,它可以在用户主目录下(全局配置),也可以在项目目录下(项目配置)。
命令 | 解释 |
---|---|
git config [--global] user.name "x00354221" |
配置用户名 |
git config [--global] user.email "xiaoxiang5@huawei.com" |
配置邮箱 |
git config --global core.autocrlf false |
防止自动转换\r\n和\n |
git config --global core.safecrlf true |
拒绝提交包含混合换行符的文件,防止\n和\r\n混用 |
git config --global core.editor "notepad++.exe -multiInst -notabbar -nosession -noPlugin" |
默认编辑器设置为notepad++,需要将notepad++所在位置加到path里 |
git config --global i18n.commitencoding utf-8 |
设置在使用git commit命令时可以输入中文 |
git config --global i18n.logoutputencoding utf-8 |
设置在使用git log命令时可以显示中文日志 |
export LESSCHARSET=utf-8 |
git设置后还需要设置LESS字符集为utf-8,之后才能正常显示中文 |
git config --global core.quotepath false |
windows环境下,设置执行git diff命令时正确显示中文路径名 |
git config --global color.ui true |
让Git显示颜色,会让命令输出看起来更醒目 |
git config --global alias.st status |
命令简写,用git st表示git status |
git config --global alias.co checkout |
命令简写,用co表示checkout |
git config --global alias.ci commit |
命令简写,ci表示commit |
git config --global alias.br branch |
命令简写,br表示branch |
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit" |
lg配置成快速查看合入图表 |
git config --list |
显示当前的Git配置 |
git config --local -l |
显示当前项目配置,配置文件位于当前项目.git\config目录下 |
git config --global -l |
显示当前全局配置,配置文件位于用户目录下的.gitconfig |
git config --system -l |
显示当前系统配置,配置文件位于以下两个地方:C:\ProgramData\Git\ 和 C:\Program Files\Git\mingw64\etc
|
git config -e [--global 或 local 或 system] |
通过编辑器的方式修改git配置文件 |
git config --global core.editor vim |
修改默认编辑器为vim |
git config -l --show-origin |
查看所有配置,对应配置所在的配置文件及其位置 |
git config --[local 或 global 或 system] --unset 配置名 |
删除[local 或 global 或 system]中的某项配置 |
增加/删除文件
命令 | 解释 |
---|---|
git add [file1] [file2] … |
添加指定文件到暂存区 |
git add [dir] |
添加指定目录到暂存区,包括子目录 |
git add . |
添加当前目录的所有文件到暂存区 |
git add -u |
只add修改和删除文件,不add新增文件 |
git add --ignore-removal . |
只add新增和修改文件,不add删除文件 |
git add -p |
添加每个变化前,都会要求确认,对于同一个文件的多处变化,可以实现分次提交 |
git add … -n |
只显示会add的文件,但实际不会添加 |
git add . -u |
添加所有文件,但忽略未追踪的文件 |
git rm [file1] [file2] … |
删除工作区文件,并且将这次删除放入暂存区 |
git rm --cached [file] |
停止追踪指定文件,但该文件会保留在工作区 |
git rm -r [dir-name] |
删除文件夹 |
git mv [file-original] [file-renamed] |
改名文件,并且将这个改名放入暂存区 |
代码提交
命令 | 解释 |
---|---|
git commit -m [message] |
提交暂存区到仓库区 |
git commit [file1] [file2] ... -m [message] |
提交暂存区的指定文件到仓库区 |
git commit -a |
提交工作区自上次commit之后的变化,直接到仓库区 |
git commit -v |
提交时显示所有diff信息 |
git commit --amend -m [message] |
使用一次新的commit,替代上一次提交,如果代码没有任何新变化,则用来改写上一次commit的提交信息 |
git commit --amend [--no-edit] [file1] [file2] … |
重做上一次commit,并包括指定文件的新变化 如果加上--no-edit选项,则不修改注释,否则提交时需要更新注释 |
git commit --allow-empt |
允许commit的时候不附带注释(不推荐使用) |
分支管理
命令 | 解释 |
---|---|
git switch [branch-name] |
切换到指定分支,并更新工作区 |
git switch -c [branch-name] |
新建一个分支,并切换到该分支 |
git switch - |
切换到上一个分支 |
git branch -m <旧名称> <新名称> |
重命名分支 |
git branch |
列出所有本地分支 |
git branch -r |
列出所有远程分支 |
git branch -a |
列出所有本地分支和远程分支 |
git branch [branch-name] |
新建一个分支,但依然停留在当前分支 |
git branch [branch] [commit] |
新建一个分支,指向指定commit |
git branch --track [branch] [remote-branch] |
新建一个分支,与指定的远程分支建立追踪关系 |
git branch --set-upstream [branch] [remote-branch] |
建立追踪关系,在现有分支与指定的远程分支之间 |
git cherry-pick [commit] |
选择一个commit,合并进当前分支 |
git branch -d [branch-name] |
删除本地分支(如果没有完全合并会失败) |
git branch -D [branch-name] |
删除本地分支(强制删除) |
git branch -dr [remote/branch] |
删除远程分支(只删除本地记录的远端信息,分支在远端实际还存在) |
git push --delete [branch-name] |
删除远程分支(会真正删除远端保存的分支) |
git merge [branch] |
合并指定分支到当前分支 |
git merge --squash [branch] |
将branch中多笔commit造成的差异合成一笔合入当前分支的工作区,提交后会产生一笔新的节点 |
git merge --no-ff -m "there is a comment" <name> |
--no-off 保存之前的分支merge历史,否则分支上的commit记录会合并到当前分支。 |
git fetch --all git reset --hard [remote]/[branch] git push -f
|
强制覆盖远端分支,本地先同步到指定节点,再强制覆盖远端分支 |
git branch [branch-name] --edit-description |
添加分支注释 |
git config branch.[branch-name].description |
查看分支注释 |
标签
命令 | 解释 |
---|---|
git tag |
列出所有tag,按照字母序,而不是时间序 |
git tag [tag] |
新建一个tag在当前commit |
git tag [tag] [commit] |
新建一个tag在指定commit |
git tag -d [tag] |
删除本地tag |
git log --pretty=oneline --abbrev-commit |
查看tag和commit的对应关系,可以用 |
git show <tagname> |
查看tag的的详细情况 |
git push origin :refs/tags/[tagName] |
删除远程tag,前提是已经删除了本地tag |
git show [tag] |
查看tag的详细信息 |
git push [remote] [tag] |
提交指定tag |
git push [remote] --tags |
提交所有tag |
git checkout -b [branch] [tag] |
新建一个分支,指向某个tag |
查看信息
命令 | 解释 |
---|---|
git status |
显示有变更的文件 |
git log |
显示当前分支的版本历史 |
git log --stat |
显示commit历史,以及每次commit发生变更的文件 |
git log -S [keyword] |
搜索提交历史,根据关键词 |
git log [tag] HEAD --pretty=format:%s |
显示某个commit之后的所有变动,每个commit占据一行 |
git log [tag] HEAD --grep feature |
显示某个commit之后的所有变动,其"提交说明"必须符合搜索条件 |
git log --follow [file] |
显示某个文件的版本历史,包括文件改名 |
git log -p [file] |
显示指定文件相关的每一次diff |
git log --oneline git log --pretty=oneline --abbrev-commit
|
显示过去提交,每条只显示一行信息,ID只显示前几位 |
git log --pretty=oneline |
显示过去提交,每条只显示一行信息,ID完整显示 |
git log --decorate --graph --oneline --all |
显示当前及之前的版本号 |
git log --graph |
显示分支合并图 |
git log --author="userName" |
列出指定用户的上库记录 |
git log --merges |
仅显示合并提交 |
git show --name-only [commit] |
显示某次提交发生变化的文件 |
git show [commit]:[filename] git show [commit] [filename]
|
显示某次提交时,某个文件的内容 |
git log --follow [file] git whatchanged [file]
|
显示某个文件的版本历史,包括文件改名 |
git shortlog -sn |
显示所有提交过的用户,按提交次数排序 |
git blame [file] |
显示指定文件是什么人在什么时间修改过 |
git reflog |
本地保存的git详细操作日志,可以通过reflog找到所有针对分支的操作 |
git rev-parse [--short=N] HEAD |
查询当前HEAD节点的commit号,长度由N指定,如果不指定长度,则默认值是core.abbrev变量的值 |
远程同步
命令 | 解释 |
---|---|
git fetch [remote] |
下载远程仓库的所有变动 |
git remote -v |
显示所有远程仓库 |
git remote show [remote] [branch] |
显示某个远程仓库的信息 |
git remote add [shortname] [url] |
增加一个新的远程仓库,并命名 |
git remote rm <repository> |
删除远程仓库 |
git pull <远程主机名> <远程分支名>:<本地分支名> |
同步远程仓库到本地,如果是合并的是当前分支,则可以不写本地分支名 |
git pull [remote] [branch] |
取回远程仓库的变化,并与本地分支合并 |
git push [remote] [branch] |
上传本地指定分支到远程仓库 |
git push [remote] --force |
强行推送当前分支到远程仓库,即使有冲突 |
git push [remote] --all |
推送所有分支到远程仓库 |
git push remote local_br_name:remote_br_name |
将本地分支推送到指定的远端,如果远端无此分支,则会新建一个 |
git push --set-upstream 分支 |
将本地分支和远端分支关联 |
撤销删除
命令 | 解释 |
---|---|
git restore --staged [file 或 .] |
恢复暂存区的指定文件或所有文件到工作区 |
git restore --worktree [file 或 .] |
撤销工作区指定文件或所有文件的改动 |
git reset --[hard 或 soft 或 mixed] CommitId |
重置暂存区与工作区,与上一次commit保持一致。 Hard:源码也会回退到某个版本,commit和index 都回回退到某个版本 Soft:保留源码,不涉及index的回退,相当于执行了git add的效果,版本间的差异都存在暂存区。 Mixed:保留源码,将git commit和index 信息回退到了某个版本.相当于版本间的差异都存在了工作区 |
git reset --hard [HEAD^ or HEAD~1] |
回退到上一个版本 |
git reset --hard [HEAD^^ or HEAD~2] |
回退到上上个版本,以此类推,一次提交即为一个版本 |
git reset --hard e9efa77 |
回退到 e9efa77 版本 |
git reset [commit] |
重置当前分支的指针为指定commit,同时重置暂存区,但工作区不变 |
git reset --keep [commit] |
重置当前HEAD为指定commit,但保持暂存区和工作区不变 |
git clean -f |
删除未Track的文件 |
git clean -fd |
删除未Track的文件和目录 |
git clean -xfd |
连 gitignore 的untrack 文件/目录也一起删掉 (慎用,一般这个是用来删掉编译出来的 .o之类的文件用的) |
git clean -n |
显示要删除的文件,但实际不会删除 |
git revert [commit] |
新建一个commit,回退所有指定commit合入的修改,并主动提交commit |
git revert -n [commit] |
回退指定的commit修改,但不主动提交commit,差异存在暂存区 |
git revert -m [1 或 2] [commit] |
如果要回退的是merge节点,则需要选择具体回退的分支,一般默认是1 |
git stash |
暂时将工作区内未提交的变化压栈 |
git stash [save "message"] |
暂时将未提交的变化移除,稍后再移入。[message]是需要加的注释 |
git stash pop [--index] [stash_id] |
将未提交的变化出栈, |
git stash pop --index |
如下为恢复最新的进度到工作区和暂存区(尝试将暂存区的改动恢复到暂存区) |
git stash pop -u |
将新增文件也暂存 |
git stash apply [--index] [stash_id] |
将堆栈中的内容应用到当前目录,不同于git stash pop,该命令不会将内容从堆栈中删除 |
git stash list |
查看所有压栈的变化列表 |
git stash drop [stash_id] |
删除已经压栈的变化 |
git stash clear |
删除所有存储的进度 |
git stash show [stash@{$num}] -p |
显示指定修改和当前目录的差异 |
PATCH操作
- 通过diff命令生成的补丁(.diff格式)不会携带git分支的信息,通过format-patch生成的补丁(.patch格式)则可以保留这些信息。
- apply和am的区别是,git apply并不会将commit message等打上去,打完patch后需要重新git add和git commit,而git am会直接将patch的所有信息打上去,而且不用重新git add和git commit,author也是patch的author而不是打patch的人
命令 | 解释 |
---|---|
git diff [file] |
显示工作区和暂存区的差异 |
git diff --cached [file] git diff --staged [file]
|
显示暂存区和本地仓的差异 |
git diff HEAD |
显示“工作目录和暂存区”与本地仓之间的的所有不相同文件的差异 |
git diff HEAD~X git diff HEAD^^^
|
可以查看最近一次提交的版本与过去数X个的版本之间的差异 |
git diff [COMMIT-ID1] [COMMIT-ID2] |
显示两次提交之间的差异,不包含ID1的修改 |
git diff --shortstat "@{0 day ago}" |
显示今天你写了多少行代码 |
git format-patch HEAD^ |
生成最近的1次commit的patch |
git format-patch <r1>..<r2> |
生成两个commit间的修改的patch |
git format-patch -1 <r1> |
生成单个commit的patch |
git format-patch <r1> |
生成某commit以来的修改patch(不包含该commit) |
git apply XX.patch git am XX.patch
|
打补丁 |
git apply --check XX.patch |
测试补丁能否能应用到当前工程 |
git apply --stat patchfile |
输出patch补丁的简要内容,比如修改了哪些文件 |
git am --abort |
当git am失败时,将所有patch废弃掉,包括之前已经打成功的 |
git am --resolved |
当git am失败,解决完冲突后,这条命令会接着打patch |
submodule
命令 | 解释 |
---|---|
git submodule add <url> <path> |
添加子模块,将其放到path指定的目录下面。可以通过git diff --cached 查看.gitmodules 中的改动 |
git submodule init git submodule update or git submodule update --init
|
主仓根目录下执行,初始化并下载子模块代码 |
git submodule update --init --recursive |
递归下载所有子模块,用于子模块下面又创建了子模块的场景 |
git clone --recurse-submodules <url> |
克隆主仓库的同时克隆模块仓库代码,这样首次初始化的时候就不需要单独再通过git submodule update 下载子模块 |
git submodule sync --recursive |
当子模块的url发生了改变,则更新前需要先执行该命令同步变化 |
submodule.<name>.shallow |
配置,设置为 true 时,此子模块的克隆将作为浅层克隆(深度为1)执行 |
# 删除子模块
rm -rf # ⼦模块⽬录删除⼦模块⽬录及源码
vi .gitmodules # 删除项⽬⽬录下.gitmodules⽂件中⼦模块相关条⽬
vi .git/config # 删除配置项中⼦模块相关条⽬
rm .git/module/* # 删除模块下的⼦模块⽬录,每个⼦模块对应⼀个⽬录,注意只删除对应的⼦模块⽬录即可
## 执⾏完成后,再执⾏添加⼦模块命令即可,如果仍然报错,执⾏如下:
git rm --cached <submodule name>
# 完成删除后,提交到仓库即可。
subtree
命令 | 解释 |
---|---|
git subtree add --prefix=<prefix> <url> |
添加url指定的git工程,将其放到prefix指定的目录下面。 |
git subtree add --prefix=<prefix> <url> <branch> --squash |
添加url指定的git工程,将其放到path指定的目录下面。squash会将所有commit记录合并为一笔。 |
git subtree pull --prefix=<prefix> <url> <branch> --squash |
更新指定的subtree目录 |
git subtree push --prefix=<prefix> <url> <branch> |
将所有对subtree的修改同步到subtree对应的仓 |
git subtree split --prefix=<prefix> --rejoin |
subtree push实际上是遍历本工程每一次提交,把提交文件涉及到subtree目录的挑出来,同步到subtree工程,如果提交有很多,遍历提交的过程是有严重的性能问题。执行split命令后,产生了一个新的分支,且这个分支和subtree push操作的逻辑一样,只把涉及subtree目录的提交摘出来了,最终这个分支合并到原分支,产生了一个Split xxxxx的提交记录。后续再执行subtree push操作,git只会检索split以后的提交,达到减少检索次数的目的,提升push性能。--rejoin就是不产生新分支,而是直接把摘出来的提交重新合入当前分支。 |
git rm <subtree> git commit
|
删除subtree,和删除普通的目录用法一样 |
# 因为每次url都输入完整的链接比较麻烦,可以先将其命名为别名,然后再直接使用就行了
# 比如下面将pico项目命名为pico_project,后面就可以直接用这个别名了
git remote add pico_project https://github.com/raspberrypi/pico-sdk.git
git subtree add --prefix=subtree/pico pico_project master
其它命令
命令 | 解释 |
---|---|
git archive |
生成一个可供发布的压缩包 |