Git 相比以前 SVN 的集中式版本控制系统有分布开发的优势,提高了团队、个体的开发效率;其特有的哈希存储系统也保证了内容的完整性(后来的区块链技术也是类似的逻辑)。
基本原理
Git 保存数据的几个(抽象)位置
- Working directory 工作目录,距离用户最近,是直接操作的那个文件夹
- Index Staging area 索引操作的舞台(临时区),可以从这里 commit 到真正的仓库
- Local repository 本地的数据仓库,进入真正的 Git 文件系统保存
- Upstream(在本地磁盘保存) 远端的 Git 库,用于分布式协作
-
Remote repository(图上未画出) 真正的远端库,用 fetch、push 进行交互。
- 其中本地仓库又分为 origin 和 local,origin branch 是远端拉取到本地的映射,通常是只读使用;local branch 是自己新创建或基于 origin branch 创建的 branch,可以直接操作
- 另外,还有一个 stash 栈区域,可以保存临时文件
- 在执行
checkout
等绝大多数命令,实际上都是在操作HEAD
文件,它标记了当前操作的位置,默认是 Staging area,也可以checkout
到某个历史 commit 进入detached
只读模式
Git 文件系统中的元素
Git 使用 hash 存储系统,系统中每个元素都形成一个 hash,通过元素中的指针记录相关关系。这样重复的文件只要一个 hash 就可以代表了,避免重复存储。
- blob 一个文件的 hash 及相关信息
- tree 一个文件夹的 hash 及其子文件的指针信息
- commit 一个仓库的快照,以 commit 链表的方式表示历史记录
- branch 由 commit 链表形成分支结构
- tag commit 的别名,比如常见别名:
HEAD
是当前 branch 最近一次 commit 的别名xxx^
xxx 可以是HEAD
、commit_hash
,表示某次 commit 之前一次 commitxxx^^
前两次 commit,依次类推xxx~1
同xxx^
,表示前一次 commit,依次类推
- index 将一个 branch 中的 commit 串联在一个历史轨迹中,index 就是这条轨迹
项目文件结构
.git
文件夹存储除工作目录外的 git 数据
- config 文件 本项目的配置文件,如果配置文件中没有描述,则使用全局配置文件的设置项
- HEAD 文件夹 本地创建的 branch 的引用信息
- refs origin 中的引用信息
- objects 真正的文件压缩数据
- hooks 一些脚本
- modules 子模块
自定义 ignore 文件忽略策略
在项目的各文件夹中可以增加.gitignore
文件,在其中配置文件忽略策略。
.gitignore
文件的作用范围是本文件夹及子文件夹,比如在整个项目中都起作用的策略可以放在根目录的.gitignore
文件中- 可以通过
git config --global core.excludesfile ~/.gitignore
设定跨项目的全局忽略策略 .gitignore
文件中可以添加对文件、文件夹的忽略,从上到下进行规则匹配(下面的覆盖前面的)- 如果某文件之前已经被版本控制了,则增加
.gitignore
并不会影响以前的文件,如果想取消之前的文件的版本控制,可以git rm --cache xxx.xx
-
如果想在 git 项目中保存空文件夹,可以在该文件夹中放入一个
.gitignore
文件来实现 .gitignore
文件语法:/
开头表示文件夹,可以放在名称开头表示根目录,名称后表示文件夹*
匹配 0 到多个字符、?
匹配单个字符[]
包含单个字符的匹配列表!
表示不忽略匹配项,用于覆盖父.gitignore
策略- 示例:
fd1/*
忽略fd1文件夹下的所有文件
,递归影响所有目录,不管是根目录还是子目录都会被忽略/fd1/*
忽略根目录中fd1文件夹下的所有文件
,只影响根目录
常用命令
config
配置项操作
git config xxx
git config [--local] configName "configValue"
默认将配置项记录在本项目的./.git/config
文件中,只在当前项目起作用。
git config --golobal configName "configValue"
使用全局配置文件,在所有未设定的项目中起作用。
git config --unset configName
删除配置项。
git config --system --unset credential.helper
删除系统记录的默认用户名密码,以便重新输入密码。
记住密码
git config --global credential.helper store
在用户主目录的 ~/.gitconfig
文件中生成下面的配置。
1 |
|
如果没有--global
,则在当前项目下的.git/config
文件中添加。
- 可以利用 git 缓存将密码记住一段时间
git config --global credential.helper 'cache --timeout=3600'
1 小时内不再重复输入密码
设定 git 操作的账号
1 |
|
PS: 注意,如果不同项目针对的是不同的法律主体,一定不要搞错了,要及时更换默认的 global 设置。否则可能发生用前一家公司的账号向新公司提交的囧况。
设置简写命令
在~/.gitconfig
中可以添加如下子命令简写:
1 |
|
init
创建一个仓库
git init
在本文件夹创建一个 git 仓库
git init xxx
在 xxx 文件夹中创建一个 git 仓库
clone
从远程 clone 一个库到本地
git clone xxx
将 xxx 库 clone 到当前文件夹,文件夹命名为 xxx,并且自动 checkout 出来其中的默认 branch,默认为 master。
git clone url_aaa bbb
clone 到 bbb 文件夹下,不实用默认的文件夹名
-n
/--no-checkout
不自动 checkout
clean
清理未被版本控制的文件,从命令执行的文件向下递归执行清理。
-
-n
dry run -
git clean
清理未被版本控制的,但不清理 ignore 的文件。 -
git clean -fX
清除被 ignore 的文件。
remote
管理远端库地址信息
git remote
显示远端库信息,origin 就是默认的一个远端库名称。
-v
verbose,查看远端库地址及其名称
git remote add originName http://xxx.xxx/xxx.git
添加一个远端库名称及其对应的远端库地址
git remote remove originName
删除远端库
git remote prune origin
参照远端库清理本地远端库分支。
本地库运行时间较长后,远端拉取的 branch 在本地的远端库会有残留,执行上面语句可以清除。
git remote rename oldName newName
重命名远程库名
git remote show origin
显示当前 branch 的远端库
status
最常用的命令,可以查看当前的 branch 及所处的状况
-u
等价于--untracked-files
,显示未跟踪的文件
checkout
直译为”检查”,意思是将文件拿过来查看、检查。在 git 中的作用是改变 HEAD,从而切换当前工作目录所处的 branch 或 commit。checkout 操作并不会影响未进入版本控制的文件。
git checkout branchName
切换到某个已存在的本地 branch 进行开发,如果不存在则自动尝试从 origin checkout 出同名 branch。
git checkout -b branchName1 remotes/origin/branchName2
以 origin branch 为 upstream 创建一个本地 branch
git checkout tagName/commit_hash/'origin/branch_name'
切换 HEAD 到一个 commit 快照或 tag,进入detached HEAD
只读模式,通常用来查看某个版本的代码。
git checkout [HEAD] filePath
从特定的 commit_hash 检出,特定文件,覆盖当前工作目录中的文件。如果不传 commit_hash 默认为 HEAD。
switch
用来替代 checkout 的分支管理功能
git switch branch_name
<=> git checkout branch_name
切换到分支
git switch -c branch_name
<=> git checkout -b branch_name
创建一个 branch
restore
用来替代 checkout 的文件恢复功能
git restore --worktree file_name...
<=> git restore -W file_name...
<=> git checkout file_name...
将工作区的文件修改还原为修改前的状态
git restore --staged <file>...
<=> git restore -S <file>...
将指定的文件还原到变更未 add 的状态,也就是 unstage 状态
git restore -s commit <file>...
将指定的文件还原到某个 commit,其中 commit 可以用 HEAD^ 等填充
add
将文件添加到 stage 准备 commit
git add xxx/xxx.xxx
添加某个文件
git add .
添加所有变更文件,包括以前没有版本控制的文件
-u
update, 添加所有已存在于 index 的变更文件-A
all, 相当于git add .
rm
将文件从 git 版本控制中删除,但是实际文件并不会被删除。
git rm xxx
从 git 版本控制中删除 xxx 文件
-r
循环删除文件夹及其中的文件
mv
重命名文件或移动文件位置
commit
将 stage 的代码提交到当前 branch
git commit
-a
add, 在 commit 前先执行git add -u
将已纳入版本控制的变更放入 stage-m
message, 后面添加 log 内容
git commit --amend -m "New commit message"
修改最后一次提交的 message,如果已经 push 过,则再次 push 时需要加 -f。
git commit --amend --reset-author
修改最后一次提交的作者信息
reset
git reset [--模式] [commit-hash]
将当前 branch 的 index 从 HEAD 设置到特定的 commit。如果不填 commit,默认是 HEAD。这个过程中会取消 stage 中的文件。
--mixed
默认模式,改变 index 但不改变 working directory--soft
只变更 HEAD 指向,index 和 working directory 都不改变,如果指向了过去的 commit,则后来的所有变更都将存在于 stage。--hard
重置 index 和 working directory,丢弃所有变更
git reset
相当于git reset --soft
,把所有已 add 到 stage 的文件返回到非 stage 状态
git reset --hard b6918745efad2fe4e5a41b65cfd0571e02410bd4
强制回退当前 branch 的主线
fetch
从远端库拉取到 Upstream 文件区
git fetch [origin]
默认 origin 为远端名称,也可以使用自己添加的远端名称
pull
执行 fetch + merge 动作
--rebase
不执行 merge 动作,改为 rebase
push
将本地版本推送到远端
git push origin br
第一次推送分支到远程
-u
upstream,在推送的同时设定当前 branch 的远端映射,适用于第一次 push
git push -d origin br
删除远程分支
log
git log [commit] [filePath]
显示每个 commit 对应的 hash 及 log message。默认以当前 branch 为主轴显示,只显示与当前 branch 有关的 commit。如果传入filePath
则围绕这个文件显示 log。
[commit]
只查看指定 commit 及之前的 log[filePath]
只查看指定文件变更的 log--graph
增加分支图的显示;--decorate
显示 commit 的引用;--simplify-by-decoration
只显示被 branch 或 tag 引用的关键 commit;--oneline
/--pretty=oneline
每个 commit 精简于一行显示,省略细节信息;--all
表示所有 branch,也可以替换为多个 branch 名;-Sstr
又名 pickaxe,对str
进行搜索,所有包含特定字符串的增加、修改的 commit 会被列出,用于找到某个特定的字符串变更所涉及的版本。-S "hello world"
可以搜索中间有空格的字符串
--grep "str"
在历史 commit message 中搜索匹配的字符串,列出这些 commit--author "str"
在历史 commit author 中搜索匹配的字符串,列出这些 commit--patch/-p
显示 log 的同时显示 patch 的内容-5
显示最近 5 条 log
git log commit_hash
显示 commit_hash 之前的 log
git log -p -5 xxx/file
查看某个文件最近 5 次的变更历史,将把变更细节也显示出来。
reflog
reflog(Reference logs) 与远端库没有直接关系,是完全保存在本地的操作记录,记录着 HEAD 的变更历史,通常用来进行回退,即使是reset --hard
的误操作都可以回退。
git reflog
查看 HEAD 的整个变更历史,显示如下:
- 原文:
123456 (HEAD -> dev, origin/dev) HEAD@{2}: checkout: moving from aaa to bbb
-
解释:
commit (当前branch, 对应的origin branch) HEAD@{2}: 动作
commit
每一行开头是 commit 的缩写,可以用来checkout
,这样可以回到任何历史版本HEAD@{2}
表示 HEAD 指针在两次移动之前的情况动作
可能是commit/checkout/pull
等
git reflog expire xxx
将过去某一时间之前的 reflog 删除
git reflog delete xxx
删除某一 reflog
git reflog exists <ref>
检查一个 ref 是否有一个 reflog
branch
git branch br
从当前工作目录创建分支,创建时并不会 checkout 到新 branch
git checkout -b new_branch_name [remotes/origin/]old_branch
创建 branch 并 checkout 到该 branch
git branch -vv
查看当前本地 branch 的信息,包括每个 branch 对应的远端 branch (upstream)名。
git branch --set-upstream-to origin/xxx
设置当前 branch 的远端 branch 名
git branch --unset-upstream
取消当前 branch 与远端 branch 的映射关系
git branch -a
查看所有 branch 信息,远端 branch 名。
git branch -D br
删除本地分支
git branch -r -D origin/br
删除本地的远程分支,-r 表示把 remotes 信息也更新
git branch -m oldName newName
重命名分支,可以重命名本地分支,然后删除远程分支重新 push
revert
git revert commit_hash1 [commit_hash1...]
将特定一个或多个 commit 代码回滚,这个回滚会作为新的一次 commit。
--contunue/skip/abort/quit
回滚过程中控制流程的开关
tag
为某个版本建立一个快照并打上标签,用于基线控制。
git tag -l ['v0.1.1.*']
列出所有的 tag,可以增加模式匹配字符串。
git checkout tagName
checkout 出 tagName 对应的版本,并进入“detached HEAD” ,只读,无法进行更改。
git checkout -b branchName tagName
checkout 出 tagName 并创建为一个 branch,可以后续修改。
git tag tagName [commit_hash]
新建一个轻量级的(lightweight)tag,相当于给 commit_hash 一个别名,默认 commit_hash 是 HEAD。
git tag -a v1.1.1 -m 'this is an annoted tag names v1.1.1' [commit_hash]
新建一个带附注(annoted)的 tag,该 tag 对应的版本将形成一个独立的存储,并包含名字、邮箱号、日期、备注、校验等信息,允许使用 GPG(GNU Privacy Guard)来签署和验证。
git push origin tagName
推送 tag 到远端
git push origin --tags
推送所有 tag 到远端
git tag -d tagName
删除本地的 tag
git push origin :refs/tags/tagName
删除了本地的 tag 后,用这条语句可以删除远端的 tag
show
--stat
只显示概要信息
git show xxx
显示某一次 commit 的内容
git show tagName
显示 tag 相关信息
diff
--stat
查看概要信息
git diff
查看当前 workspace 已经发生的变更
git diff xxx/xxx
查看具体文件在当前 workspace 下发生的变更
git diff hash1 hash2 --stat
查看两次 commit 的概要差异,左边是旧版本、右边是新版本,这里的 hash1 hash2 只需要输入一部分就可以了
git diff HEAD^ HEAD
commit 名称即使用前缀也不容易记忆,可以使用最近几次 commit 的别名:HEAD
、HEAD^
、HEAD^^
…,分别表示 最后一次 commit、倒数第二次、第三次…
git diff hash1 hash2 xxx1/xxx1.xx [xxx2/xxx2.xx]
查看两次 commit 的某[些]文件的具体差异
git diff hash1 hash2
查看两次 commit 的所有文件的具体差异
git diff branch1 branch2
查看两个 branch 的差异,其他操作类似 hash
rev-parse
将特定的引用解析为 commit
git rev-parse HEAD
查看 HEAD 对应的 commit
format-patch
生成 patch 文件,与git apply
命令配合可以打补丁包。与 linux 自带的 patch 相比更适合多层级多文件的情况,另外还保留了 commit log。生成的文件名形如:0001-this-is-commit-log.patch
,前面是一系列补丁中的序号、后面是由 commit log 中非特殊字符拼接的。
git format-patch hash1[..hash2]
将(hash1, hash2]生成一系列带序号的 .patch 文件。可以用的几个版本别名:--root
、HEAD
、HEAD^
、HEAD^^
…,分别表示 初始无 commit 状态、最后一次 commit、倒数第二次、第三次…
git format-patch -1 hash
只生成一个 commit 对应的 patch,-1
表示左边版本与右边版本的距离,这里表示前面 1 个版本。
-o folderPath
将生成的补丁(组)输出到指定文件夹
patch 文件语法
从上到下描述文件中各个段的意义:
-
From xxx Mon Sep 17 00:00:00 2001
commit_hash 及 协议版本时间 -
From: CodeHunter <CodeHunter2006@gmail.com>
commit 提交者签名 -
Date: Tue, 19 Nov 2019 20:11:04 +0800
生成补丁的时间 -
Subject: [PATCH] [bugfix]: xxx
commit 的 log message -
以分割符
---
开头,表示变更概览内容,变更的文件、文件增+
减-
行数、总的变更数
1 |
|
-
diff --git a/xxx/xxx.go b/xxx/xxx.go
开始描述具体变更的文件,左边a...
是变更前文件,右边b...
是变更后文件 -
index 1aa17cf..677c50c 100644
变更前后索引的变化,左边是变更前,右边是变更后 -
表示开始描述具体文件变更内容
1 |
|
-
@@ -544,17 +544,15 @@ func xxx
表示下面的文字内容是从文件的 544 行往后变更了 17 行,变成了 15 行(删除了两行),右边是 544 行对应的文本 -
接下来就是具体的行的变更
-
表示删除,+
表示增加,-
紧接着+
表示替换
1 |
|
-
接下来是重复的 6 ~ 10 描述不同文件的变更
-
最后是结束分割符和 patch 文件协议版本号
1 |
|
apply
应用一个 patch,将变更加到当前的工作目录,之后需要自己手动进行 commit 的操作。
git apply xxx/xxx.patch
打一个补丁文件
--stat
查看 patch 的概要情况--check
检查是否能够打上,如果没有报错则说明可以打上--reject
强行打补丁,冲突的部分会保存为.rej
文件
am
apply manager,批量执行 apply 动作,自动进行 commit。
git am xxx/*.patch
按照文件序号打上一系列补丁文件
--signoff
在打补丁时在 commit log 中加上自己的签名,有时可能使用的是别人的补丁包
git am --abort
放弃之前打上的补丁
git am --resolved
与--continue
等价,打补丁冲突后,手动解决了冲突,然后执行这条命令继续打 patch
cherry-pick
选定特定的一些 commit,合并到当前工作目录
git cherry-pick <commit>...
将一个或多个 commit 合并到当前工作目录。
-n
no-commit,合并后不提交,需手动继续操作-ff
fast-forward,如果 HEAD 与当前 commit 一致,则自动 fast-forward--continue/skip/abort/quit
合并过程遇到冲突、手动处理后的命令,继续/跳过/放弃/保留现场并退出
-m 1/2
如果某个 commit 正好是一次 merge,则它包含两个父节点。用 1 2 区分两个父节点。其中 1 表示时间最近的那次父节点,即 merge 的目标分支。
merge
将源 branch 的所有新增 commit,按顺序合并到当前工作目录 branch。
git merge br
git merge --continue
继续 merge,将源 branch 的 commit 逐步放入当前 branch
git merge --abort
放弃本次 merge 过程,恢复到当前工作目录 branch merge 前的状态
git merge --quit
放弃本次 merge 过程,并停留到当前状态
rebase
有时我们需要将当前 branch 的 commit 全部提出,然后在目标 branch 上有选择行的逐一 commit 上去,并且可能修改 commit log。rebase 命令就为这个场景提供了一系列方便的操作。将当前工作目录所在 branch 的所有 commit 提出到临时区域,直到找到与 rebase 目标 branch 同根的 commit,然后将目标 branch 作为当前 branch 的根,将临时区域的 commit 逐个选择、编辑 log、commit。整个过程 HEAD 将发生逐步移动。
git rebase br
以 br 为目标 branch,进行 rebase 动作。遇到冲突时会暂停,手工解决后继续;或回滚,放弃 rebase。
git rebase --continue
继续 rebase,将缓冲区的 commit 逐步放入当前 branch
git rebase --skip
没有实际的文件冲突,只是有冲突标记,可以跳过本次冲突,继续 rebase
git rebase --abort
放弃本次 rebase 过程,恢复到当前工作目录 branch rebase 前的状态
git rebase --quit
退出 rebase 过程,但保留现场。由于缺少最新代码,将导致当前工作 branch 无法正常工作。
git rebase -i hash_old [hash_new]
以交互模式,将当前的 branch 在(hash_old, hash_new]
(左开右闭)区间内执行一次 rebase 操作,每条 commit 将被重新给予变更机会。范围可以用HEAD
等名称。交互模式将以文本显示、修改、退出、执行的方式进行。
操作流程:
- 显示出交互界面——一个 VIM 文本编辑界面(commit 处理方式选择)
- 编辑文本、准备好待执行的命令(commit 处理方式选择/位置上下调换)
- 退出编辑
:q
,同时执行编辑中的命令,继续 rebase - 处理冲突/编辑 log
- 退出编辑
:q
,同时执行编辑中的命令,继续rebase --continue
- 中间阶段时,会在 4 ~ 5 之间循环,直到完成 rebase 或放弃
rebase --abort
- 注意,不同版本显示的界面版本顺序可能不同,要看清新旧版本是从上到下还是从下到上排列
在交互时修改每条 commit 前的标记,在退出文本后就会按照标记进行 rebase。下面是可用的标记及功能说明:
1 |
|
stash
以栈的形式将临时变更缓存在当前 git 库的公共区域,在需要时可以恢复、继续使用。只有在版本控制的文件会被存入缓存区。
show pop drop
丢弃栈顶
也可以加具体缓冲位置为参数stash@{1}
距离栈顶 1 个距离的位置
git stash [comment]
将临时未 stage 的变更缓存在栈中
git stash list
查看栈列表
git stash show
显示栈顶变更概要
git stash show -p
显示栈顶变更具体 diff 内容
git stash apply
将栈顶内容应用到当前工作目录
git stash drop
丢弃缓存栈的栈顶
git stash pop
出栈一次,将变更覆盖到当前工作空间,相当于 apply + drop
git stash clear
清空整个缓存栈
git stash save stashname
保存当前变更代码为指定名称
git stash -p
以交互模式执行 stash 动作,选择指定的 hunk(代码块),退出该模式时完成选择执行 stash 动作。
y
yes stage this hunkn
do not stage this hunkq
quit; do not stage this hunk nor any of the remaining onesa
stage this hunk and all later hunks in the filed
drop; do not stage this hunk nor any of the later hunks in the fileg
select a hunk to go to/
search for a hunk matching the given regexj
jump; leave this hunk undecided, see next undecided hunkJ
leave this hunk undecided, see next hunkk
leave this hunk undecided, see previous undecided hunkK
leave this hunk undecided, see previous hunks
split the current hunk into smaller hunkse
manually edit the current hunk?
print help
blame
blame 直译为”责备、归责”,用来查看某行代码是谁在哪个版本修改的。
git blame file_name
以 blame 模式查看某文件,在每行会显示这行最后修改的版本号、日期、时间、作者。
如果找到了某个位置变更的版本号,但是想继续追查,可以 checkout 出对应的版本号,然后再次执行 blame,就能查到更久的历史了。
-L startLine [endLine]
显示的行号范围-C
显示该片段的原始 commit,可能是从其他文件 copy 过来的。
bisect
通过交互式的二分查找过程找到引入问题的版本,每次人工判断前 git 会自动 checkout 出一个版本,然后人工检查后输入结果(good/bad),然后自动继续 checkout 出另一个历史版本,直到找到第一次出错的版本。
git bisect start [new_hash [old_hash]]
开启一次二分查找过程,其中new_hash
和old_hash
指定查找范围,如果不指定则查找到当前版本为止的历史 commit。
git biset good/bad
人工检查当前版本结果后输入,不断测试,直到最后输出hash_xxx is the first bad commit
为止git biset reset
退出本次查错过程,返回到 start 之前的版本
submodule
将项目的子模块信息绑定在当前项目中,提供一些方便的更新操作。
- 多个 git 项目想依赖同一个子模块时有下面三种办法:
- 将子模块的文件夹放在当前项目外面,通过相对地址访问
- 将子模块放在当前项目里,设置
.gitignore
文件忽略子模块文件夹 - 用 submodule 将子模块所属 git 版本信息绑定到当前项目,以提供一些方便操作
对于比较复杂的项目,方案 3 比较合适,在提交本项目信息时也将当时子项目版本记录下来一并提交,以便之后别人维护项目时使用。方案 3 中的子项目是一个独立的项目,可能被多个父项目依赖,对父项目的存在无感知,它与父项目的关联关系仅限于在父项目的 config 等位置有版本相关绑定信息。
通常子模块是独立开发,然后在父项目中执行 update 后使用。但是也可以在父项目中直接修改子模块,然后 cd 到子模块文件夹中进行 git 操作提交。
git submodule add sub_git_url [path]
将 sub_git_url 对应的 git 库添加为当前库的 submodule,设置 path 可以指定子模块的目录位置,不设置则放在根目录使用默认的库名称。
执行完命令后,根目录会增加一个.gitmodules
文件并且.git/config
文件中也会增加对应的子模块信息,此操作本身可以作为一次 commit 提交。
-b <branch>
指定 submodule 默认 checkout 出的 branch,如果在创建时没有指定,可以用git submodule set-branch xxx
设定--name <name>
指定 submodule 的 name,默认与 submodule 项目名一致
git clone xxx_url --recurse-submodules
在 clone 时同时进行 submodule 的初始化,如果在 clone 时没有初始化,之后可以用git submodule init
初始化
git submodule init
在 clone 时没有初始化,可以用这个初始化。
git submodule update
更新所有 submodule
--recursive
递归更新 submodule 的 submodule
git submodule deinit sub_module_name
卸载一个子模块,同时从多个文件中删除绑定信息
--force
即使 submodule 中有
git submodule foreach 'git checkout dev'
批量对所有 submodule 执行同一个命令
--recursive
递归 submodule
archive
类似 svn 的 export 功能,将指定的 branch 导出为压缩文件,不会包含工作空间的多余文件。 注意在根目录使用命令,否则会只导出子目录文件。
git archive --output "../test.zip" master
将 master 中的文件导出到 “../test.zip” 压缩包中,根据”xxx.zip”自动采用 zip 格式压缩
--format tar.gz
可以指定压缩算法,如果没有指定,则根据指定的 output 文件后缀自动选择压缩算法
示例场景
从 dev 创建 branch_my 进行开发,完毕后 merge 到 dev 然后提交
1 |
|
从 dev 创建 my 进行开发,通过 MergeRequest 提交代码到 dev。
1 |
|
拷贝了不同 PC 上的 git 项目文件夹,缺少了 upsteam 信息
1 |
|
通过上面语句可以补足上游信息,branchName 可以相同也可以不同。
在 github 上 fork 出一个库,开发后发出 MergeRequest
默认开发 branch 是 dev
1 |
|
- 一般由项目的 Owner 负责 MR(Merge Request) 的 CR(Code Review) 和 Merge 动作, 然后发出 Pull Request,以便各个 Fork 出的 Repository 升级
将git format-patch
生成的一系列文件补丁打到项目、解决冲突
1 |
|
把一些常用的临时代码打成 patch 文件,需要时使用
1 |
|