Git 分支:解决多人协同开发时,保证每个人之间的开发不影响其他人的开发进程,每个人之间的开发是独立的,互不影响的。
git branch 查看现有的分支 或 创建新的分支
当不带任何命令参数时,输入git branch可以帮助查看当前项目所拥有的全部分支。并且Git会使用*来标明我们当前所处的分支上。
$ cd /d/git_my_project
HP@LAPTOP-C23SQRD2 MINGW64 /d/git_my_project (master)
$ git branch
* master
增加新的分支
# 创建issue102的分支
git branch issue102
# 查看现有的所有分支
git branch
issue102
*master
git checkout命令切换到新建的issue102分支上
$ git checkout issue102
Switched to branch 'issue102'
D REASME
A readme
D readme.txt
# 切换分支
git checkout issue102
# 在分支上创建下新的文件
touch issue102.md
git add issue102.md
git commit -m "update issue102.md"
[issue102 edfa387] update issue102.md
3 files changed, 1 deletion(-)
delete mode 100644 REASME
create mode 100644 issue102.md
rename readme.txt => readme (100%)
touch issue102.html
git add issue102.html
git commit -m "update issue102.html"
git log --oneline检查下当前Git的记录。
以issue102合并到master上为例子进行演示。
# 切换回主分支
git checkout master
# 使用git merge 进行合并
git merge issue102
# git branch --no-merged
# 查看所有未合并工作的分支
可以发现原来在issue102分支上的文件已经合并到了主分支上了,并且issue102分支还存在。
有时候分支的合并不会一番顺利,当我们在两个分支中对同一个文件的同一个部分进行了不同的修改,Git就没有办法顺利的合并他们,会在合并的时候产生合并冲突。比如我们在issue102分支和master分支下对issue102.md文件进行了修改,当我们将issue102分支融合到主分支上时就会发生冲突。
可以通过git status查看命令来查看那些因包含合并冲突而处于未合并(unmerged)状态的文件。
当出现矛盾后,合并的文件内容将会出现"<<<<<<“,”=======“,”>>>>>>"等分割线来进行标记。
出现了矛盾时,我们需要进行手动解决或者放弃合并。
手动合并:选择我们要保留的代码,然后再把>>>>>, ======, <<<<<<这些提示行给去掉。最后重新进行add commit的操作即可。
放弃合并:当发现冲突所导致的改动量很大时,我们可以选择放弃该次的合并。可以使用git merge --abort放弃此次的融合。如果我们在运行了git merge之后又进行了一些人为的改动,那么在abort之后,所进行的改动也会被回滚掉。
git mergetool:它会将找到一份两个分支的祖先代码作为base(基准),然后再将两个分支的改动都列举出来作为对比,让我们在git编辑器当中决定要留下什么。
首先,我们可以使用git remote -v查看远程库的详细信息。会显示我们可以抓取或推送的origin地址。
git remote -v
当我们需要推送本地分支到远程时,需要指定具体的本地分支。
# 推送本地的master分支到远程
git push origin master
# 推送本地的issue102分支到远程
git push origin issue102
但是当我们多人协作进行开发的时候,可能会出现远程分支比我们本地更新的情况,这时,我们就需要使用 git pull 的命令来试图合并。如果合并出现冲突时,我们需要解决冲突再提交。
在Git中没有什么分支是不可以删除的(除了当前所在的分支不能删除),包括master分支也是可以进行删除。 Git的分支删除可以分为删除本地分支和远程分支。
删除本地分支
# branchName 是需要删除的本地分支名字
# 当我们想强行删除分支时,只需要将参数d改为D即可。
git branch -d branchName
删除远程分支
# origin 是远程的主机名
# branch 需要删除的远程分支
git push origin --delete branch
当我们需要重命名分支的名称时,我们可以使用git branch命令来进行,具体方式如下:
# oldBranchName: 旧分支名
# newBranchName :新分支名
git branch -m oldBranchName newBranchName
当我们想要将改名后的分支推送到远程时,我们需要进行如下操作:
git branch -m oldBranchName newBranchName # 将本地的分支进行重命名
git push origin newBranchName # 将新的分支推送到远程
git push --delete origin oldBranchName # 删除远程的旧的分支
考虑使用一种怎样的方式使我们最大化的使用分支操作的优点。
在整个项目开发周期的不同阶段,我们可以同时拥有多个分支;
然后我们可以定期地把某些主题分支合并入其他分支中。
许多使用 Git 的开发者都喜欢使用这种方式来工作,比如只在 master 分支上保留完全稳定的代码——有可能仅仅是已经发布或即将发布的代码。
他们还有一些名为 develop 或者 next 的平行分支,被用来做后续开发或者测试稳定性——这些分支不必保持绝对稳定,但是一旦达到稳定状态,它们就可以被合并入 master 分支了。
这样,在确保这些已完成的主题分支(短期分支,比如之前的 issue102 分支)能够通过所有测试,并且不会引入更多 bug 之后,就可以合并入主干分支中,等待下一次的发布。
短期分支也可以叫做主题分支,它的作用是用来实现某一种特性或者相关工作(修复bug,开发产品新特性)。比如当我们的产品出现了bug时,我们应该新建一个分支并起名为bug分支,并在该分支上进行bug的修复,等我们的代码确定不会引起其他bug时,我们就可以合并到主分支上进行修复。当我们看见issue时,我们也可以使用同样的方式来解决issue的问题。常见的短期分支还有上面提到的develop,topic分支。在实际开发中,我们应该按照以下几个基本原则进行分支开发工作流程
本章主要介绍 Git 常用的工具,可能不会经常用到,但是“万一”呢,你说对吧? 看看总归不会有坏处,技多不压身嘛
fork 这个演示项目至你的个人账号下
可以通过任意一个提交的 40 位字符的 SHA-1散列值来指定它。
$ 是终端交互的提示符,不需要输入。如果系统或者终端不一样,只需输入$后的内容即可,
$ git log | more
commit 44328544187650f2f6ecc253ef3a2b099c51baa5
Author: Martin Xu <[email protected]>
Date: Wed May 4 13:41:55 2022 +0800
add model module
从日志能明显的看到多次提交的记录,每次包括 commit + 一串字符、作者、提交时间 和详细信息等。
切换至本项目工作目录,执行 git log 能看到类似提交日志的输出。(shell 通过 pipe | 将输出信息传递给 more 做多页显示)。
想查看某次提交信息,可以通过 git show 来查看
$ git show 44328544187650f2f6ecc253ef3a2b099c51baa5
查看所有所有提交 SHA-1 字符串
$ git log|grep '^commit'|awk '{print $2}'
44328544187650f2f6ecc253ef3a2b099c51baa5
a55ea122894272b13c3a43129ca0b74cfd2b6a4a
Git 在没有歧义的情况下,通过前几个字符来替代上述 40 位字符,如上可简化成:
$ git show 4432854
$ git show 4432
可以在 git log 后加 --abbrev-commit 参数,输出结果就会显示简短且唯一的值了。默认情况使用 7 个字符,有时为来避免歧义,会增加字符数。
通过在 git log后增加 --pretty=oneline简化输出内容
$ git log --abbrev-commit
$ git log --abbrev-commit --pretty=oneline
要查看一个分支的最后一次对象,可以通过分支名查看。查看本地分支列表通过git branch查看
$ git branch
develop
main
* stable
查看远程分支通过后加参数-r
$ git branch -r
pdd/main
通过git show stable查看指定分支最后一次提交信息
git show stable
fatal: ambiguous argument 'stable': both revision and filename
Use '--' to separate paths from revisions, like this:
'git [...] -- [...]'
Git 不知道如何处理,我们需要通过 – 明确告知
$ git show -- app
在工作时, Git 会在后台保存一个引用日志(reflog), 引用日志记录了最近几个月你的 HEAD 和分支引用所指向的历史。
$ git reflog
5de18d5 (HEAD -> main, origin/main, origin/HEAD) HEAD@{0}: clone: from https://github.com/Lily0630/app
当 HEAD 所指向的位置发生了变化,Git 就会将这个信息存储到引用日志这个历史记录里。 也可以通过 reflog 数据来获取之前的提交历史。 如果你想查看仓库中 HEAD 在 0 次前的所指向的提交,你可以使用 @{n} 来引用 reflog 中输出的提交记录。
$ git show HEAD@{0}
当修改大量文件后,希望将改动拆分成多个提交而不是一起提交的时候,可以通过如下命令操作。
如果运行 git add 后加 -i 或者 --interactive 选项的时候,Git 会进入一个交互式命令模式,如:
可以看到这个命令以和平时不同的视图:显示了暂存区。基本上与 git status 是相同的信息,但是更简明扼要一些。 它将暂存的修改列在左侧,未暂存的修改列在右侧。
$ git add -i
staged unstaged path
1: +532/-0 nothing src/trace/events.go
2: +365/-0 nothing src/trace/histogram.go
3: +325/-0 nothing src/trace/histogram_test.go
4: +1130/-0 nothing src/trace/trace.go
5: +178/-0 nothing src/trace/trace_test.go
*** Commands ***
1: status 2: update 3: revert 4: add untracked
5: patch 6: diff 7: quit 8: help
What now>
在这块区域后是 Commands 命令区域。 在这里你可以做一些工作,包括暂存文件、取消暂存文件、暂存文件的一部分、添加未被追踪的文件、显示暂存内容的区别。
在 Waht now>> 提示符后输入u或者2,它会提示你要暂存哪个文件
在 Waht now>> 提示符后输入u或者2,它会提示你要暂存哪个文件
What now> u
取消暂存,在 Waht now>> 提示符后输入r或者3
查看已暂存内容的区别,可以使用 d 或 6(区别)命令。跟在命令行指定 git diff --cached 非常相似
#退出
What now> q
通过这些基本命令,可以使用交互式添加模式 来轻松地处理暂存区。
Git 也可以暂存文件的特定部分。 例如,如果在 TODO 文件中做了两处修改,但只想要暂存其中的一个而不是另一个,Git 会轻松地完成。
输入p 后,选择你需要操作的文件后,直接敲回车,会逐一询问你是否需要暂存他们,(1/1) 表示当前是第 1 个初变更,共 1 处变更。
$ git add -i
What now> p
通过y或者n来选择是否要暂存每一区块,当然也可以通过a暂存从这到后面所有当前文件的修改。暂存成功后,退出交互命令,我们就可以通过git commit来提交这部分暂存的文件了。
y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk or any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk or any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
e - manually edit the current hunk
? - print help
在当前分支上工作了一段时间后,东西变得很混乱。你想切换至新的分支而又不想放弃放弃的修改,或者纯粹想先做其他分支的事情的时候,就该git stash上场了。
git status文件被修改了一大坨,但是还没修改完,暂时还不想提交,而我又想切换至新的分支,这时候就需要stash,先把变更推送至栈上,运行git stash 或者 git stash push
git stash
stash 会处理工作目录的的状态,跟踪文件的修改和暂存的改动,然后将未完成的修改保存至一个栈上,这样就可以在后续任何时间切换回来。
要返回刚才那坨文件该怎么办呢?通过 git stash list 查看所有 stash 的列表
$ git stash list
切换至最后 stash 变更
git stash apply
获取指定的的变更:如果有多个,可以通过 git stash apply stash@{n} 中的 n 来获取指定的的变更。
删除 stash 的内容:可以通过 git stash drop 或者 git stash pop 来删除 stash 的内容
$ git stash drop stash@{0}
对于一些不需要的文件或目录,需要的是清理 它而不是保存修改记录
git clean
会移除未被跟踪的文件
git stash --all 来移除所有文件并保存到栈上
移除工作目录中所有未追踪的文件以及空的子目录。 -f 意味着强制移除,使用它需要 Git 配置变量,clean.requireForce 没有显式设置为 false。
使git clean -f -d
HP@LAPTOP-C23SQRD2 MINGW64 /d/git_my_project/app (main)
$ touch temp; mkdir log; mkdir target; touch target/main
HP@LAPTOP-C23SQRD2 MINGW64 /d/git_my_project/app (main)
$ git clean -n
Would remove temp
HP@LAPTOP-C23SQRD2 MINGW64 /d/git_my_project/app (main)
$ git clean -n -x
Would remove temp
HP@LAPTOP-C23SQRD2 MINGW64 /d/git_my_project/app (main)
$ git clean -n -x -d
Would remove log/
Would remove target/
Would remove temp
HP@LAPTOP-C23SQRD2 MINGW64 /d/git_my_project/app (main)
$
如果想交互删除,可以通过选项 -i来操作
查找一个函数是在哪里调用或者定义的,或者显示一个方法的变更历史。 Git 提供了两个有用的工具来快速地从它的数据库中浏览代码和提交。
默认情况下git grep会查找你的工作目录文件。
Git Grep
通过-n或者--line-number显示匹配的行号
通过-c或者--count输出统计信息
通过-p 或者 --show-function 显示每个匹配字符串所在的方法或函数
通过git log可以很强大的知道一些特定的提交信息
git log -S percentileBoundary
通过-L选项进行行日志搜索,它可以展示代码中一行或者一个函数的历史。
$ git log -L :percentileBoundary:src/trace/histogram.go
如果 Git 无法匹配到你的函数或者方法,可以通过正则表达式,如这个命令和上面是等效的
$ git log -L '/percentileBoundary/',/^}/:src/trace/histogram.go
项目中经常会遇到包含另外一个项目,如:第三方库,或者你将自己的项目切分成多个子项目,然后在其他项目中引用,如,将项目中的 model 独立处理,独立维护;其他项目组引用这个项目,并不维护 model。这里我们可以将 model 做子项目添加到当前项目中。
后面的看 链接,写了半天没保存啊啊啊啊啊啊啊啊啊啊啊啊啊啊!!!
后续:以上整理了一些常用工具,还有一些高级的功能,如签名、凭证存储、重置、Rerere 等功能未整理。