Git指令學(xué)習(xí)筆記

rebase

多人在同一個分支上協(xié)作時,很容易出現(xiàn)沖突。即使沒有沖突,后push的童鞋不得不先pull,在本地合并,然后才能push成功。那么怎么才能讓提交歷史變得干凈,易讀呢?可以使用rebase對某一段線性提交歷史進行編輯、刪除、復(fù)制、粘貼;因此,合理使用rebase命令可以使我們的提交歷史干凈、簡潔!




$ git rebaseFirst,?

rewinding head to replay your work on top of it...Applying:add commentUsingindex info to reconstruct a base tree...Mhello.pyFallingback to patching baseand3-way merge...Auto-merging hello.pyApplying:add authorUsingindex info to reconstruct a base tree...Mhello.pyFallingback to patching baseand3-way merge...Auto-merging hello.py


reset

git reset命令用于將當前HEAD復(fù)位到指定狀態(tài)。一般用于撤消之前的一些操作(如:git add,git commit等)。

git reset [-q] [] [--] …?

git reset (--patch | -p) [] [--] […?]

git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] []

在第一和第二種形式中,將條目從<tree-ish>復(fù)制到索引。 在第三種形式中,將當前分支頭(HEAD)設(shè)置為<commit>,可選擇修改索引和工作樹進行匹配。所有形式的<tree-ish>/<commit>默認為HEAD。

這里的HEAD關(guān)鍵字指的是當前分支最末梢最新的一個提交。也就是版本庫中該分支上的最新版本。

在git的一般使用中,如果發(fā)現(xiàn)錯誤的將不想暫存的文件被git add進入索引之后,想回退取消,則可以使用命令:git reset HEAD <file>,同時git add完畢之后,git也會做相應(yīng)的提示,


Submodule

當項目越來越龐大之后,不可避免的要拆分成多個子模塊,我們希望各個子模塊有獨立的版本管理,并且由專門的人去維護,這時候我們就要用到git的submodule功能。

常用命令

git clone <repository> --recursive 遞歸的方式克隆整個項目

git submodule add <repository> <path> 添加子模塊

git submodule init 初始化子模塊

git submodule update 更新子模塊

git submodule foreach git pull 拉取所有子模塊


創(chuàng)建project版本庫,并提交readme.txt文件

git init --bare project.git

git clone project.git project1

cd project1

echo "This is a project." > readme.txt

git add .

git commit -m "add readme.txt"

git push origin master

cd ..

創(chuàng)建moduleA版本庫,并提交a.txt文件

git init --bare moduleA.git

git clone moduleA.git moduleA1

cd moduleA1

echo "This is a submodule." > a.txt

git add .

git commit -m "add a.txt"

git push origin master

cd ..

在project項目中引入子模塊moduleA,并提交子模塊信息

cd project1

git submodule add ../moduleA.git moduleA

git status

git diff

git add .

git commit -m "add submodule"

git push origin master

cd ..

2. 克隆帶子模塊的版本庫

方法一,先clone父項目,再初始化submodule,最后更新submodule,初始化只需要做一次,之后每次只需要直接update就可以了,需要注意submodule默認是不在任何分支上的,它指向父項目存儲的submodule commit id。

git clone project.git project2

cd project2

git submodule init

git submodule update

cd ..

方法二,采用遞歸參數(shù)--recursive,需要注意同樣submodule默認是不在任何分支上的,它指向父項目存儲的submodule commit id。

git clone project.git project3 --recursive

?修改子模塊

cd project1/moduleA

git branch

echo "This is a submodule." > b.txt

git add .

git commit -m "add b.txt"

git push origin master

cd ..

git status

git diff

git add .

git commit -m "update submodule add b.txt"

git push origin master

cd ..

更新子模塊

方法一,先pull父項目,然后執(zhí)行g(shù)it submodule update,注意moduleA的分支始終不是master。

cd project2

git pull

git submodule update

cd ..

方法二,先進入子模塊,然后切換到需要的分支,這里是master分支,然后對子模塊pull,這種方法會改變子模塊的分支。

cd project3/moduleA

git checkout master

cd ..

git submodule foreach git pull

cd ..

5. 刪除子模塊

網(wǎng)上有好多用的是下面這種方法

git rm --cached moduleA

rm -rf moduleA

rm .gitmodules

vim .git/config

刪除submodule相關(guān)的內(nèi)容,例如下面的內(nèi)容

[submodule"moduleA"]? ? ? url =/Users/nick/dev/nick-doc/testGitSubmodule/moduleA.git

然后提交到遠程服務(wù)器

git add .

git commit -m "remove submodule"


.reflog

  如果在回退以后又想再次回到之前的版本,git reflog 可以查看所有分支的所有操作記錄(包括commit和reset的操作),包括已經(jīng)被刪除的commit記錄,git log則不能察看已經(jīng)刪除了的commit記錄

Administrator@USER-20171026MG MINGW64 ~/Desktop/lyf?(master)

$ git reflog

e1bdff6 (HEAD -> master) HEAD@{0}: commit: 第二次提交

62e6739 HEAD@{1}: reset: moving to HEAD^

8113f0d HEAD@{2}: reset: moving to HEAD^

dc6bb4e HEAD@{3}: reset: moving to dc6bb4e

8113f0d HEAD@{4}: reset: moving to HEAD^

dc6bb4e HEAD@{5}: commit: my.txt增加44444內(nèi)容

8113f0d HEAD@{6}: commit: 文件增加33333內(nèi)容

62e6739 HEAD@{7}: commit (initial): my第一次提交



執(zhí)行g(shù)it blame;命令時,會逐行顯示文件,并在每一行的行首顯示commit號,提交者,最早的提交日期

給具體文件執(zhí)行$git blame后的效果如下

6c2414fb (liangfei 2014-05-12 05:32:01 -0400? 1) from markdown import markdown

be442bb4 (liangfei 2014-05-09 10:26:27 -0400? 2) from django.shortcuts import render

be442bb4 (liangfei 2014-05-09 10:26:27 -0400? 3) from django.core.paginator import Paginator, InvalidPage, EmptyPage

be442bb4 (liangfei 2014-05-09 10:26:27 -0400? 4) from blog.models import Post, Category

be442bb4 (liangfei 2014-05-09 10:26:27 -0400? 5)

be442bb4 (liangfei 2014-05-09 10:26:27 -0400? 6)

be442bb4 (liangfei 2014-05-09 10:26:27 -0400? 7) def category(request, cat_name, page_num=1):

be442bb4 (liangfei 2014-05-09 10:26:27 -0400? 8)? ? if cat_name.lower() == 'home':

be442bb4 (liangfei 2014-05-09 10:26:27 -0400? 9)? ? ? ? posts = Post.objects.all().order_by('-date')

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 10)? ? else:

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 11)? ? ? ? posts = Post.objects.all().filter(category__name=cat_name).order_by('-date')

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 12)

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 13)? ? paginator = Paginator(posts, 3)

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 14)? ? try:

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 15)? ? ? ? page = int(page_num)

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 16)? ? except ValueError:

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 17)? ? ? ? page = 1

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 18)

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 19)? ? try:

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 20)? ? ? ? posts = paginator.page(page)

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 21)? ? except (InvalidPage, EmptyPage):

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 22)? ? ? ? posts = paginator.page(paginator.num_pages)

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 23)

6c2414fb (liangfei 2014-05-12 05:32:01 -0400 24)? ? for post in posts:

6c2414fb (liangfei 2014-05-12 05:32:01 -0400 25)? ? ? ? post.body = markdown(post.body)

6c2414fb (liangfei 2014-05-12 05:32:01 -0400 26)

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 27)? ? return render(request, 'blog/index.html',

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 28)? ? ? ? ? ? ? ? ? {

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 29)? ? ? ? ? ? ? ? ? ? ? 'posts': posts,

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 30)? ? ? ? ? ? ? ? ? ? ? 'cat_now': cat_name,

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 31)? ? ? ? ? ? ? ? ? ? ? 'cat_all': map(lambda cat: cat.name, Category.objects.all())

be442bb4 (liangfei 2014-05-09 10:26:27 -0400 32)? ? ? ? ? ? ? ? ? })


git stash 的作用

git stash用于想要保存當前的修改,但是想回到之前最后一次提交的干凈的工作倉庫時進行的操作.git stash將本地的修改保存起來,并且將當前代碼切換到HEAD提交上.

通過git stash存儲的修改列表,可以通過git stash list查看.git stash show用于校驗,git stash apply用于重新存儲.直接執(zhí)行g(shù)it stash等同于git stash save.



開發(fā)到一半,同步遠端代碼

當你的開發(fā)進行到一半,但是代碼還不想進行提交 ,然后需要同步去關(guān)聯(lián)遠端代碼時.如果你本地的代碼和遠端代碼沒有沖突時,可以直接通過git pull解決.但是如果可能發(fā)生沖突怎么辦.直接git pull會拒絕覆蓋當前的修改.

遇到這種情況,需要先保存本地的代碼,進行g(shù)it pull,然后再pop出本地代碼:

git stash

git pull

git stash pop

工作流被打斷,需要先做別的需求

當開發(fā)進行到一半,老板過來跟你說"線上有個bug,你現(xiàn)在給我改好,不然扣你雞腿".當然,你可以開一個新的分支,把當前代碼提交過去,回頭再merge,具體代碼如下

繁瑣的工作流示例# ... hack hack hack ...git checkout -b my_wip git commit -a -m"WIP"git checkout master edit emergency fix git commit -a -m"Fix in a hurry"git checkout my_wip git reset --soft HEAD^# ... continue hacking ...

我們可以通過git stash來簡化這個流程

正確姿勢# ... hack hack hack ...git stash//保存開發(fā)到一半的代碼edit emergency fix git commit -a -m"Fix in a hurry"git stash pop//將代碼追加到最新的提交之后# ... continue hacking ...

提交特定文件

如果對多個文件做了修改,但是只想提交幾個文件,或者想先暫時保存幾個修改,測試其他文件的執(zhí)行結(jié)果.可以通過git stash save --keep-index來進行.

# ... hack hack hack ...git add --patch foo//只將第一部分加入管理the indexgit stash save --keep-index//將其余部分保存起來edit/build/test first part git commit -m'First part'//提交全部的git管理中的代碼git stash pop//繼續(xù)進行存儲代碼的工作# ... repeat above five steps until one commit remains ...edit/build/test remaining parts git commit foo -m'Remaining parts'

恢復(fù)被錯誤clear/drop的存儲

如果因為失誤對存儲倉庫進行了clear或者drop操作,在一般機制下是不能恢復(fù)的.但是可以通過以下指令來獲取仍在倉庫中的,但是已經(jīng)不可獲取的存儲列表

git fsck --unreachable |grep commit | cut -d\? -f3 |xargs gitlog--merges --no-walk --grep=WIP



git fetch

git fetch從遠程分支拉取代碼。

fetch常結(jié)合merge一起用,git fetch + git merge == git pull

一般要用git fetch+git merge,因為git pull會將代碼直接合并,造成沖突等無法知道,fetch代碼下來要git diff orgin/xx來看一下差異然后再合并。

作者:憶飛

鏈接:http://www.itdecent.cn/p/a5c4d2f99807

來源:簡書

簡書著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請聯(lián)系作者獲得授權(quán)并注明出處。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容