git使用技巧(原文:git深度使用經驗總結)

已經開始使用Git了,有些時候一般的問題只能Google就能找到答案,但是有些時候不能找到答案,因爲遇到的問題都不知道該用什麼關鍵字搜索。很多是在Git中文的QQ羣中討論出來的,把一些經驗總結一下:

1.Git子模塊

使用情況:例如Android系統代碼和app之間可以使用這種submodule的方法來管理。

快速上手:

$ git submodule add url path/to/name 

$ git submodule init

$ git submodule foreach git pull

其它情況下submodule不適用,可以用subtree來代替。

clone代碼以及pull時候要這樣更新:
git submodule update


2.同步一個COMMIT

$ git cherry-pick xxx

可以同步一個commit到本分支


3.Git打TAG

打TAG也就是發佈版本

$ git tag -a v1.2 -m "version 1.4"

$ git push --tags

如果還不能理解可以到這裏看看是linus是怎麼給linux內核打的TAG,TAG看起來像什麼:https://github.com/torvalds/linux/releases


4.查看status詳情

$ git add xxx

$ git diff --cached

這樣可以在commit之前先看一下修改詳情。


5.不產生無用的merge的同步

有這麼一種情況,用一個分支專門同步代碼提供商的代碼的時候,如果一般的pull會不斷的產生一個merge看起來會很煩,用下邊的使用添加一個--rebase就不會產生無用的merge了

$ git pull --rebase origin master


6.關於stash

適用情況:做了修改後,還沒有add commit等等後續工作,現在突然要切換分支做其它事情,默認情況下你在這個分支修改的代碼會被帶到切換過去的分支中。可以先把你修改的保存起來。這些修改可以再還原過來。

$ git stash -u

$ xxxx 隨便你的操作

$ git stash pop

注意:-u是代表是也把添加的新文件(術語是未跟蹤)也藏起來,一般是要有這個u的。


7.恢復一個COMMIT

如果一個COMMIT你不想要了,想要去除,可以考慮使用以下的方法;

$ git revert xxxx

這個就可以去掉這個COMMIT的改動,這個是明式的去掉,如果你又後悔了,還可以再次恢復。


8.安裝最新Git版本

能輕易安裝的一般不會是最新的,用apt-get install便是如此。下面用離線的方式安裝Git。

$ sudo apt-get install libssl-dev libcurl4-openssl-dev libexpat1-dev

a先到https://github.com/git/git/releases看最新版本,然後複製鏈接。紅色隨具體版本變化。

$ apt-get remove git # 卸載現有

sudo apt-get install libssl-dev libcurl4-openssl-dev libexpat1-dev #安裝必要的庫

$ wget https://github.com/git/git/releases/tag/v1.8.4.3 (鏈接地址)

$ tar xvzf v1.8.4.3.tar.gz

$ cd git-v1.8.4.3

$ make prefix=/opt/git all

$ make prefix=/opt/git install

$ 添加/opt/git/bin到環境變量中 /etc/environment中,或者其它。


9.安裝subtree 

$ git clone https://github.com/apenwarr/git-subtree

$ cp git-subtree/git-subtree.sh /opt/git/bin/git-subtree

關於使用的subtree的幾個帖子:

使用git subtree集成項目到子目錄

一個成功的Git分支模型


10.Git之本地忽略

這個分同種情況:a是本地永久忽略,效果的gitignore一樣,只不過不適於寫到gitignore中而已,可以自己建立一個本地獨享的gitignore,然後git config --global core.excludesfile  文件的絕對路徑,也可以直接將本地要忽略的文件添加到.git/info/exclude中。不過上述都是針對沒有跟蹤的文件來說的,如果文件已經被跟蹤了你如果在本地想要忽略它的改動,就不能使用以上的方法了。這正情況b。通俗地講比如一個編譯Android的腳本在其它電腦上都是使用的-j32來編譯的,但是你的電腦配置沒有別人的好,不能開到-j32,但是這個腳本是已經跟蹤過的,你修改了就會在每次的git status中看到。對於這種情況Git有一個忽略改動的方法:

$ git update-index --assume-unchanged /path/to/file       #忽略跟蹤

git update-index --no-assume-unchanged /path/to/file  #恢復跟蹤


之後你在本地修改/path/to/file這個文件,Git也不管它了。就實現了本地忽略。


11.Gitlab用戶頭像的問題

如果裝的Git服務器是GitLab的話,是可以使用用戶頭像的,GitLab管理頭像的一般方法是用gravatar,這一點和github一樣,是關聯email地址的,先在上邊註冊一個賬戶,上傳一個頭像並關聯某一個郵箱,Gitlab或者Github會自動去gravatar上拉取你的個人頭像。


12.Git打包源碼

對Git管理的源碼進行壓縮打包,如果使用tar xvzf xxxx.tag.gz xxxxx的話並不是一個很好的選擇,因爲會將.git/目錄下的中間文件全部壓縮,如果只想要某一個版本的源碼。Git提供了archive.它會給打包一份純淨的代碼。當然這個只適用於發部一個版本的源碼,而不是備份Git管理的整套源碼。

$ git archive xxxx

xxx代表SHA-1 Hash值。


13.Git反向打補丁

一套沒有管理有源碼,中間有功能A,且也有功能A的補丁文件,可以使用補丁文件進行反打補丁來實現去掉功能A。

$ git apply -R

注:只是收集,還沒有完整測試這裏


13.關於Git服務器選擇和安裝

選擇建議GitLab,安裝我參考加總結這幾個帖子:

1.《 gitlabhq / doc / install / installation.md 》根據國情爲官方的安裝方法添加了說明的安裝文檔。

2.《 在 Ubuntu 12.04 上安裝 GitLab6.x》一個對安裝過程打印信息都記錄的安裝文檔,安裝過程中可以對比安裝過程。

3.《重設MySQL root密碼》中間遇到的問題MySQL密碼找不到了,這篇文章給了答案。


14.合併commit

1.《使用git合併多個提交

2.《git如何合併只有兩個commit到一個?


15.Git只clone最新版本代碼不要.git目錄

這個也是在羣中出現了問題,我曾經也有過這樣的需求,想法是好的,但是理解是錯誤的。如果只要最後一個版本的代碼,而不要.git目錄中的東西,有辦法:

git clone --depth=1 git://someserver/somerepo dirformynewrepo
rm -rf !$/.git
但是這又說明不是要參與開發的,是使用的。使用一般是要使用代碼開發最新發布版本,如果只要最新的提交版本是沒有用處的。因爲它不是穩定的。這樣就引入了發佈版本這一說明,Git中是打Tag,一個tag是一個版本,可以以剛纔的需求去找最後一個tag版本。github上是可以直接下載某一個tag版本的。如果要用git clone來完成,會複雜一些。現在的github是結合了web的,例如github或者是自己搭建的gitlab都是可以直接從web上下載指定的tag版本。而沒有用於版本控制的.git目錄。


16.關於pull和merge

都在提倡添加--no-ff選項。



17.刪除子模塊-解決子模塊自動找上門的問題
    也許你並不想要用子模塊,但是有時它會自動找上門,那麼你要了解一下怎麼去除它了。怎麼個自動上門,且聽我慢慢道來。
    在項目A中,如果用git clone了另外一個項目B,或許你只是想把項目B的代碼添加到項目A中,但是這時執行git status/add的時候會發現項目B中的代碼,並不會被添加,也就是說不能被跟蹤。這是爲什麼呢,這裏因爲會自動將項目B做爲了子模塊管理,就是因爲它是一個包含.git目錄的完整的工程。解決這個問題有同種方法:
1.在clone項目b的後立即將項目B中的.git目錄刪除
2.git rm --cached path/to/B
然後再執行git status/add 之類的命令就會可以正常的跟蹤了。

18.恢復一個文件到之前的某個提交
    這個種情況一般是出在某個bug解決後整理規範代碼的時候,解決這個bug的時候可能添加了不少的調試代碼,最後解決後,有些調試信息只爲了瞭解代碼流程,對以後並沒有保留的意義,所以就要將其恢復開始解決這個bug之前的提交。xxxxx代表開始解決這個bug之前的一個提交的哈希碼。
對於已經跟蹤的文件:
1.git reset xxxxxx path/to/file
2.git checkout path/to/file
對於沒有跟蹤的文件:
1.git rm path/to/file

19.合併時只產生合併提交
    還有其它說法:合併時不合並歷史;合併時將所有commit合爲一個。
git pull --squash another
    話說一般用於master分支,像linus的linux內核一樣。

更多信息見《Git merge no history commit》《git merge –squash介紹

20.關於GUI Clients

這裏《GUI Clients》。

21.git pull 前簡單審查
情況是這樣的:本人管理的是develop分支,其他人管理的他們自己的分支。所以應該每次改動的都應該是package/apps下的文件,但是有一種情況是我擔心他們會不小心改到系統代碼並提交了。在合併之前查看都改了哪些文件。這樣就能有效地防止誤修改。

和老友溝通後,得出以下結論:
1.讓他們添加本地忽略,忽略他們一定不會改的目錄。
2.在每次合併代碼的時候,看一下每個分支都修改了哪些文件,有沒有系統文件被修改
3.使用grrit。
4.先git fetch 再merge。
最後選擇了第二種。因爲git pull後,提交的時候會顯示出這次合併代碼都有哪些修改。


22.Gitk 不錯的查看Log的工具


23.Git遇上代碼規範

Git遇上代碼規範會有些事情要處理好,這裏寫先寫個經典的:

1.檢測自己要提交的代碼中有無table

一般多人開發的程序中不準使用table代替空格的,以下是GoogleJava代碼規範(中文)中的截圖:

 

所以在提交代碼前自檢一下自己代碼中有有無table是很有必要的。

$ git diff | grep -P “\t” | grep “+”

如果tab已經存在,這裏有很好的解決方案,所以項目代碼不要急於commit前期工作很重要。


24.You are in the middle of an am session.

$ git status

On branch hardware

You are in the middle of an am session.

  (fix conflicts and then run "git am --continue")

  (use "git am --skip" to skip this patch)

  (use "git am --abort" to restore the original branch)

 

nothing to commit, working directory clean

對於這個情況,我是在接手一個別人的倉庫的時候遇到的,我目前沒有更好的方法,也不知道做了哪些事情,我採取的是 重新clone一份代碼。


25.Git鏡像-簡易倉庫

working tree/bare tree/remote tree

一般情況下沒有這個需求,做鏡像一般是中轉服務器。

  $ git clone --mirror xxx.git

     執行以上命令將會clone一個裸版庫,正常clone下來的是代碼版本的庫。前者不是用來編輯的,它本身是一個Git服務器上的倉庫,可以供客戶端進行pullpush。這其實也算是一個簡易的Git服務器了。

在這個裸版庫中,沒有pullpush,有的只是

$ git remote update

會和遠程庫更新爲遠程倉庫的內容。如果裸版倉庫中比遠程更新,那麼會執行類似git reset --hard的指令強制更新爲遠程的。所以執行這個命令的時候要小心。因爲它會洗掉本地與遠端不同的內容「1」。在bare tree也沒有什麼類似git pull的功能。


26.獲取遠程tags.

git fetch --tags


27.添加空目錄

    $ find . -type d -empty -exec touch {}/.gitignore \;

    執行以上命令將會在空目錄中添加一個.gitignore文件,這樣就可以保證空目錄不被忽略,且不影響原代碼的結構。

    來自:git 如何添加空目錄 

28.新建立android系統源碼倉庫時要加--force選項以強制添加已經被忽略的文件

gitignore 新建立android系統源碼倉庫注意事項
第一次添加文件是一定要加上--force選項 添加所有文件(包括被忽略的文件),因爲子目錄中會有.gitignore忽略一些對Android系統很必要的文件。如external/dbus會忽略config.h,但這個文件很重要。沒有它就編譯不過。也有可能是dbus子項目的.gitignore寫錯了,也有可能是故意忽略。
總之強制添加config.h後就不會再被刪除。

說Android只是一個例子,大的項目都需要考慮一下。

關於config.h爲什麼會被忽略,前邊加有說明 對Android很必要,因爲Android編譯和普通linux系統上編譯庫的方法不一樣。android不是通過./configure自動生成config.h。Android系統是要一個已經好的config.h通過Android.mk的方式進行編譯。

29."get_tz_offset" is not exported by the Git module

執行git cvsimport -v test_project時出現的錯誤,升級爲最新版本2.2.1沒有問題了。

轉自:http://blog.csdn.net/kangear/article/details/13169395

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章