Master the Git

What is Git?

Git 是文件分布式管理系统。每一个文件都有对应的hash,任何对文件的更改都可以被记录下来。
Git 在local和remote都有保存代码库,可以有效防止代码丢失。
Master(main) 即是project主线,branch支线。主线支线可以合并。
Git 强大的version control可以使开发者自由地切换版本。
Git的submodule功能解决了共享dependency的问题,减少了代码的重复。
一个git project可以想象成一棵树,每个节点都有一个对应的版本(hash id),我们可以沿着树枝切换到不同的版本上。

常见概念

远程分支 origin

git log 查看历史

查看Git 历史:
git log --oneline
git log --oneline --all

git push 提交代码

提交代码时首先要和上游更新,再提交,否则会报错(因为git log不一样)。
git push
如果想强行提交用 git push --force

git diff

git diff --cached ./path/to/file
When git diff is invoked with the --cached option the diff will compare the staged changes with the local repository. The --cached option is synonymous with --staged.

git branch 新建,推送与删除

git stash

git stash
git stash pop
暂时将手头上的工作放在一边

在开发的许多时候我们都需要使用git提供的分支管理功能。

1.新建本地分支:git checkout -b test 新建一个名为:test 的本地分支。

2.提交本地分支:git push origin test:test 将本地的test分支推送到远程仓库的test 分支上。(test:test中的第一个的test表示本地分支名字,第二个test表示远程分支名字)

3.删除本地分支:git branch -D test 删除本地的分支

4.删除远程分支:git push origin :test 本命令推送了一个空的分支到远程的test分支,等同于删除远程分支。

Rebase vs Merge

Merge 两个branch会产生非线性的git log。
Rebase 后提交历史是线性的,更清晰明了。
在团队开发中,我更倾向于用rebase. Never use merge, make your life easy!

git checkout branch,pull时用 git pull --rebase
push 时如果更改了log tree 需要force push: git push --force

https://git-scm.com/book/be/v2/Git-Branching-Rebasing

如何找到代码的作者(背锅侠)

git blame file_name

如何把branch 上的更新push到master上?(cherry pick)

push的granularity把握好:整理commit,squash后,把主要的更新push到master上。

  1. git rebase -i
    把需要的commit 放在最上方. squash the redundent commit using s.
    use f (fix) also works.

  2. 查看某一个commit是什么?
    git show hash_id
    https://blog.csdn.net/w57685321/article/details/86597808

  3. push需要的commit到master
    git push origin hash:master

如何在branch上pull master?

  1. 将master set 成upstream,这样master有更新时,git pull --rebase 可以更新整个log tree。
    git branch --set-upstream-to=origin/<branch>

如何在branch 上pull 指定branch?

git pull origin <remote_branch_name> --rebase

撤回commit

git reset --hard HEAD^

撤回git pull

git reflog
git reset --hard hash_id

关于 git submodule (子模块)

https://git-scm.com/book/en/v2/Git-Tools-Submodules
https://zhuanlan.zhihu.com/p/87053283
submodule 是git一个很好的新功能,解决了library dependency的问题。面对复杂的项目,我们因为开发需要将代码拆解成不同的子模块。主项目对子模块有依赖关系,但开发过程相对独立。 当main project需要include sub-project 时,我们无需copy sub-project到当前project下,只需sub-project设为main project的submodule。这样main project 和 sub project 的版本管理可以互相独立。当sub project 更新时,我们只需在main project里git submodule update.

子模块内容的更新:

  1. 本地有更新
  2. 本地submodule 版本有更新
  3. 远程有更新

Add a submodule

An HTTPS URL like https://github.com/user/repo.git
An SSH URL, like git@github.com:user/repo.git
Use ssh url when possible.

git submodule [--quiet] add [<options>] [--] <remote_repo_url> [<local_path>]
.gitmodule config file is created.

[submodule "third_party/abseil-cpp"]                                                                                                                
    path = third_party/abseil-cpp   # local directory of the submodule                                                                                                                
    url = git@github.com:abseil/abseil-cpp.git  # remote submodule url (can be absoule or relative url)

git commit -am "add new submodule"
git push origin master

Delete a submodule

# 逆初始化模块,其中{MOD_NAME}为模块目录,执行后可发现模块目录被清空
git submodule deinit {MOD_NAME} 
# 删除.gitmodules中记录的模块信息(--cached选项清除.git/modules中的缓存)
git rm --cached {MOD_NAME} 
# 提交更改到代码库,可观察到'.gitmodules'内容发生变更
git commit -am "Remove a submodule." 

Commit message

$ git commit -am 'Add DbConnector module'
[master fb9093c] Add DbConnector module
 2 files changed, 4 insertions(+)
 create mode 100644 .gitmodules
 create mode 160000 DbConnector

Notice the 160000 mode for the DbConnector entry. That is a special mode in Git that basically means you’re recording a commit as a directory entry rather than a subdirectory or a file.

Clone a project with submodules

By default, when you clone a project with submodules, you only get the directories but no files.

git clone --recurse-submodules project_url

or

git submodule init # register to the remote submodule path
git submodule update --recurse-submodules # downloading submodule files

--recurse-submodules automatically initialize and update nested submodules.
Fool Proof (in case you forgot):

git submodule update --init --recursive

Working with submodules

1. Submodule User - Pulling changes from submodules or projects with submodules

git submodule update --remote: pull the lastest changes based on the remote submodule. 
if no --remote is added, it pulls the most recent updates from the main module.
git config -f .gitmodules submodule.DbConnector.branch stable  # change the branch of the submodule to update for everyone(by changing the .gitmodules file)

note: This command will by default assume that you want to update the checkout to the master branch of the submodule repository.
git pull does not update the submodules by default!!!
Always use git submodule update --init --recursive after each git pull.

2. Submodule Dev - Publishing submodule changes

making changes to the main project and the submodule at the same time.
Recommend to work on the submodule in its own repo to avoid confusion.(Simplify our life rather than complicate the shit!)

$ git push --recurse-submodules=check
The following submodule paths contain changes that can
not be found on any remote:
  DbConnector

Please try

    git push --recurse-submodules=on-demand

or cd to the path and use

    git push

to push them to a remote.

Submodule Foreach

Other Commands

在主repo查看submodule的commit hash id
git submodule
初始化submodule
git submodule update --init submodule_path
更新某个submodule
git submodule update --remote submodule_path
update single submodule
git submodule update --init <specific relative path to submodule>
更新所有submodule
git pull --recurse-submodules
用这个方法更新后,submodule的version和main repo HEAD指定各submodule的version一样。

redo commit

git reset --soft HEAD~
git push -f

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容