目录
git branch
git 分支可以理解为代码的平行世界,你可以在任意一个平行世界里开发代码,其他的平行世界不受影响,Git 的分支模型称为必杀技特性,而正是因为它,将 Git 从版本控制系统家族里区分出来;真正改变你的开发模式
举两个分支管理的应用场景
场景一
假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。
现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作
场景二
假设一个公司有一套代码,面向不同的客户,每个客户都有自己的客制化功能;如果全部提交到git 上,非常冗余。有了git 的分支技术,就很方便。给每个客户都创建一个单独的分支,如果代码要release 给客户,也可以做到不同客户之间的代码相互保密。

git branch create
git checkout BranchName # switch to an exist branch
git checkout -b BranchName # create and switch to a new local branch
git branch -d BranchName # delete a local branch
git 查看分支
git branch -av # show all branches
git branch -r # show remote branches
git branch # show local branches
git branch BranchName # create a new local branch
从远程分支 checkout 出来的本地分支,称为_跟踪分支(tracking branch)_。跟踪分支是一种和远程分支有直接联系的本地分支。在跟踪分支里输入git push,Git 会自行推断应该向哪个服务器的哪个分支推送数据。反过来,在这些分支里运行 git pull 会获取所有远程索引,并把它们的数据都合并到本地分支中来。就是将本地分支和远程的分支相互关联
在克隆仓库时,Git 通常会自动创建一个名为 master 的分支来跟踪 origin/master。这正是 git push 和 git pull 一开始就能正常工作的原因。当然,你可以随心所欲地设定为其它跟踪分支,比如 origin 上除了 master 之外的其它分支。
git checkout branchname --track Remote name/BranchName # create and switch to a new branch to track remote branch
比如:
git checkout -b c_cn_9380_yst_cn_an_cus-cus --track aosp/c_cn_9380_yst_cn_an_cus-cus
git checkout -t 远程的分支 直接切到追踪远程的分支
分支合并
一旦某分支有了独立内容,你终究会希望将它合并回到你的主分支

你可以使用以下命令将任何分支合并到当前分支中去
git checkout master // 切换到Master分支
git merge --no-ff develop // 对Develop分支进行合并 --no-ff 参数的含义:
默认情况下,Git执行"快进式合并"(fast-farward merge),会直接将 Master 分支指向 Develop 分支。
使用 --no-ff 参数后,会执行正常合并,在 Master 分支上生成一个新节点。
git cherry-pick
git cherry-pick + <commit hash>
cherry-pick 命令应用于需要将其他分支的 commit 合并到当前分支的情形,cherry-pick 之后会生成一笔新的提交。

git blame
git blame +文件名
通过 git blame 命令,我们可以查出某个文件的每一行内容到底是由哪位大神所写;可以非常方便的定位问题
git patch
本身 Linux 命令里有 diff 和 patch 两个命令可以生成 patch 和打 patch,但是有两个缺点值得注意:
对单个文件或者多个文件,diff 和 patch 这两个文件比较方便。对于 git 这种以 project 为单位的修改,尤其是涉及到多个文件夹下的多个文件的改动时,就很不方便,无法保存commit的信息。
git 本身带有patch 的命令,git 生成patch 的命令如下:
git format-patch HEAD^
生成最近的1次commit的patch
git format-patch HEAD^^
生成最近的2次commit的patch
$ git format-patch <r1>..<r2>
生成两个commit间的修改的patch(包含两个commit. 和都是具体的commit号)
git format-patch -1 <r1>
生成单个commit的patch
$ git format-patch <r1>
生成某 commit 以来的修改 patch(不包含该commit)
$ git format-patch --root <r1>
生成从根到r1提交的所有patch
合入patch 的命令:git am 和 git apply
git apply --stat 0001-limit-log-function.patch
查看patch的情况
git apply --check 0001-limit-log-function.patch
检查patch是否能够打上,如果没有任何输出,则说明无冲突,可以打上
(注:git apply是另外一种打patch的命令,其与git am的区别是,git apply并不会将commit message等打上去,打完patch后需要重新git add和git commit,而git am会直接将patch的所有信息打上去,而且不用重新git add和git commit,author也是patch的author而不是打patch的人)
$ git am 0001-limit-log-function.patch
将名字为0001-limit-log-function.patch的patch打上
$ git am --signoff 0001-limit-log-function.patch
添加-s或者–signoff,还可以把自己的名字添加为signed off by信息,作用是注明打patch的人是谁,因为有时打patch的人并不是patch的作者
git am ~/patch-set/*.patch
将路径~/patch-set/*.patch 按照先后顺序打上
$ git am --abort
当git am失败时,用以将已经在am过程中打上的patch废弃掉(比如有三个patch,打到第三个patch时有冲突,那么这条命令会把打上的前两个patch丢弃掉,返回没有打patch的状态)
git am --resolved
当 git am 失败,解决完冲突后,这条命令会接着打patch
git rebase
把一个分支的修改合并到当前分支。
假设现在我基于远程的分支(master)建立一个名为A的本地分支,我们在这个分支做一些修改,然后生成两个提交(commit),有些人也在"master"分支上做了一些修改并且做了提交了. 这就意味着"master"和"A"这两个分支各自"前进"了,它们之间"分叉"了。

在这里,你可以用pull命令把master分支上的修改拉下来并且和你的修改合并; 结果看起来就像一个新的"合并的提交"(merge commit):

但是,如果你想让"A"分支历史看起来像没有经过任何合并一样,你也许可以用 git rebase:
git checkout A
git rebase master
这些命令会把你的"A"分支里的每个提交(commit)取消掉,并且把它们临时保存为补丁(patch)(这些补丁放到".git/rebase"目录中),然后把"A"分支更新 为最新的"origin"分支,最后把保存的这些补丁应用到"A"分支上。

在 rebase 的过程中,也许会出现冲突(conflict). 在这种情况,Git会停止 rebase并会让你去解决 冲突;在解决完冲突后,用"git-add"命令去更新这些内容的索引(index), 然后,你无需执行 git-commit,只要执行:
git rebase --continue
这样git会继续应用(apply)余下的补丁。
在任何时候,你可以用–abort参数来终止rebase的行动,并且"mywork" 分支会回到rebase开始前的状态。
git rebase --abort
另外,我们在使用git pull命令的时候,可以使用–rebase参数,即git pull --rebase,这里表示把你的本地当前分支里的每个提交(commit)取消掉,并且把它们临时 保存为补丁(patch)(这些补丁放到".git/rebase"目录中),然后把本地当前分支更新 为最新的"origin"分支,最后把保存的这些补丁应用到本地当前分支上。
将多笔提交合并为一个提交

git rebase -i 命令可以压缩合并多次提交
格式:git rebase -i [startpoint] [endpoint]
其中-i的意思是 –interactive,即弹出交互式的界面让用户编辑完成合并操作,[startpoint] [endpoint ]则指定了一个编辑区间,如果不指定[endpoint],则该区间的终点默认是当前分支 HEAD 所指向的 commit (注:该区间指定的是一个前开后闭的区间)。
// 合并从当前head到15abd5678 (commit id)
git rebase -i 15abd5678
或:
// 合并最近的两次提交
git rebase -i HEAD~2
执行这个命令后会跳到一个vi编辑器
里面的提示有:
-
pick:保留该commit(缩写:p)
-
reword:保留该commit,但我需要修改该commit的注释(缩写:r)
-
edit:保留该commit, 但我要停下来修改该提交(不仅仅修改注释)(缩写:e)
-
squash:将该commit和前一个commit合并(缩写:s)
-
fixup:将该commit和前一个commit合并,但我不要保留该提交的注释信息(缩写:f)
-
exec:执行shell命令(缩写:x)
-
drop:我要丢弃该commit(缩写:d)
保存之后会弹出对话框让你修改你的 commit message,修改完成之后保存就可以了。
如果 rebase 的内容需要丢弃,要使用 git rebase --abort
git submodule
git submodule sync
git submodule --init --rescursive
github
GitHub 是一个面向[开源]及私有[软件]项目的托管平台,因为只支持 Git 作为唯一的版本库格式进行托管,故名 GitHub
在这里我们将 github 作为一个远程 git 仓库使用,在 github 你可以新建自己的代码仓库,提交,下载,管理代码
Github 需要提前注册,网上有很多教程,这里不再赘述了
tips: 实际在操作中发现,因为国内的某些原因,github 的连接不稳定
git clone 的时候出现失败的问题
git clone https://github.com/tony-chenwang/source_code.git
Cloning into 'source_code'...
fatal: unable to access 'https://github.com/tony-chenwang/source_code.git/': Failed to connect to github.com port 443: Connection refused
这个时候打开github 的网页地址试试看:
https://github.com/tony-chenwang/source_code
能正常打开之后,再clone 版本仓库试试看:

github 创建远程代码仓库
登录到自己的 github 主页
网页左上角的 Repositories ==> New 进入下面的网页

-
代码仓库的名称,可以自己定义
-
代码仓库的描述,相当于对代码仓库的注释信息,会出现在下面的readme 文件中
-
该代码仓库是公开还是私有的
公开:所有人都可以下载
私人:只有自己可以下载
-
新建代码仓库的时候自带一个readme文件,作为初始化信息
-
点击创建自己的代码仓库
创建完成的代码仓库如下图:

github clone 远程仓库到本地
点击 code,复制远程的代码仓库地址

在 ubuntu 上 clone 远程仓库
tony-chen@DESKTOP-54IDJCR:/mnt/d/Ubuntu$ git clone https://github.com/tony-chenwang/demo_repo.git
Cloning into 'demo_repo'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
tony-chen@DESKTOP-54IDJCR:/mnt/d/Ubuntu$
github 修改文件提交到本地仓库
tony-chen@DESKTOP-54IDJCR:/mnt/d/Ubuntu/demo_repo$ git status
On branch main
Your branch is up to date with 'origin/main'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
NdkImage.h
nothing added to commit but untracked files present (use "git add" to track)
git add .
git commit 添加自己的注释


github push 到远程分支
tony-chen@DESKTOP-54IDJCR:/mnt/d/Ubuntu/demo_repo$ git push origin HEAD:origin/HEAD
Username for 'https://github.com': 604848340@qq.com
Password for 'https://604848340@qq.com@github.com':
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 6.39 KiB | 1.60 MiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote:
remote: Create a pull request for 'remotes/origin/HEAD' on GitHub by visiting:
remote: https://github.com/tony-chenwang/demo_repo/pull/new/remotes/origin/HEAD
remote:
To https://github.com/tony-chenwang/demo_repo.git
* [new branch] HEAD -> remotes/origin/HEAD
Git进阶与GitHub实战指南
1948

被折叠的 条评论
为什么被折叠?



