Git常用命令

配置及幫助相關(guān)

設(shè)置配置:git config --global user.name "John Doe"
查看配置及出處:git config --show-origin rerere.autoUpdate
查看幫助:git help <verb>

基本命令

將目錄初始化為git目錄:git init
克隆已有的項(xiàng)目:git clone https://github.com/libgit2/libgit2 mylibgit
查看文件狀態(tài):git status -s
移除文件:git rm (-f參數(shù)強(qiáng)制移除被修改的文件,如果文件被修改了官份,默認(rèn)是不會(huì)被移除的)
取消文件跟蹤:git rm --cached
移動(dòng)文件:git mv file_from file_to
查看歷史:git log (-p:顯示差異;-2:最近兩次記錄河咽;--stat:文件狀態(tài))
自定義格式歷史記錄及合并路徑:git log --pretty=format:"%h - %an, %ar : %s" --graph
從標(biāo)記中回退:git reset HEAD <file>
退回到上次提交的版本:git checkout -- <file>
查看遠(yuǎn)端:git remote -v
添加遠(yuǎn)端:git remote add <shortname> <url>
拉取數(shù)據(jù):git fetch/git pull
推送數(shù)據(jù):git push <remote> <branch>
查看本地與遠(yuǎn)端分支對(duì)應(yīng)情況:git remote show origin
重命名/刪除遠(yuǎn)端:git remote rename pb paul / git remote remove paul
查看/查找tag:git tag/git tag -l "v1.8.5*"
創(chuàng)建匿名tag:git tag -a v1.4 -m "my version 1.4"
補(bǔ)打tag:git tag -a v1.2 9fceb02
推送tag:git push origin v1.5/git push origin --tags
刪除本地/遠(yuǎn)端tag:git tag -d <tagname>/git push origin --delete <tagname>
牽出tag:git checkout 2.0.0
基于tag創(chuàng)建分支:git checkout -b version2 v2.0.0

分支

git commit記錄與blob.png

創(chuàng)建分支:git branch testing
切換分支:git checkout testing
創(chuàng)建并切換分支:git checkout -b <newbranchname>
合并分支:git merge hotfix
刪除分支:git branch -d hotfix
查看分支:git branch (-v:顯示最后commit飒房,--merged/--no-merged:過(guò)濾已經(jīng)合并/未合并到當(dāng)前分支的分支狠毯,git branch --no-merged master:是否合并到master的分支)
同步到遠(yuǎn)程分支:git push <remote> <branch> (git push origin serverfix 等效于 git push origin refs/heads/serverfix:refs/heads/serverfix)
創(chuàng)建本地分支并跟蹤對(duì)應(yīng)的遠(yuǎn)程分支:git checkout -b <branch> <remote>/<branch> / git checkout --track origin/serverfix / git checkout <branch>
設(shè)置本地分支的跟蹤遠(yuǎn)程分支:git branch -u origin/serverfix
顯示本地分支與遠(yuǎn)程分支的對(duì)應(yīng)情況:git branch -vv
更新本地git數(shù)據(jù):git fetch --all
更新本地git數(shù)據(jù)并合并當(dāng)前分支:git pull
刪除遠(yuǎn)端分支:git push origin --delete <branch>
變基:git rebase <branch>
取出client分支嚼松,找出處于client(client是基于server開(kāi)出的分支)分支和server分支的共同祖先之后的修改惜颇,然后把她們?cè)趍aster分支上重新放一遍: git rebase --onto master server client
變基遠(yuǎn)端:git pull --rebase

Git服務(wù)器

克隆裸倉(cāng)庫(kù):git clone --bare my_project my_project.git
將裸倉(cāng)庫(kù)放置到服務(wù)器上:scp -r my_project.git user@git.example.com:/srv/git
通過(guò)git將倉(cāng)庫(kù)目錄的組權(quán)限設(shè)置為可寫:git init --bare --shared
SSH Key目錄:cd ~/.ssh
創(chuàng)建sshkey:ssh-keygen -o
打印sshkey公鑰:cat ~/.ssh/id_rsa.pub
創(chuàng)建git用戶和對(duì)應(yīng)的.ssh目錄

  $ sudo adduser git
  $ su git
  $ cd
  $ mkdir .ssh && chmod 700 .ssh
  $ touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys

添加用戶公鑰:cat /tmp/id_rsa.john.pub >> ~/.ssh/authorized_keys
創(chuàng)建并初始化git:

  $ cd /srv/git
  $ mkdir project.git
  $ cd project.git
  $ git init --bare

已經(jīng)設(shè)置了git用戶和git倉(cāng)庫(kù)的服務(wù)器,快速添加新項(xiàng)目:

  $ cd myproject
  $ git init
  $ git add .
  $ git commit -m 'initial commit'
  $ git remote add origin git@gitserver:/srv/git/project.git
  $ git push origin master

限制git用戶活動(dòng)在與git相關(guān)范圍內(nèi):

  $ cat /etc/shells   # see if `git-shell` is already in there.  If not...
  $ which git-shell   # make sure git-shell is installed on your system.
  $ sudo -e /etc/shells  # and add the path to git-shell from last command
  $ sudo chsh git -s $(which git-shell)

分布式Git

生成patch:git format-patch -M origin/master
應(yīng)用patch:git am 0001-limit-log-function.patch
查看不在master上的commit:git log contrib --not master
查看當(dāng)前分支與目標(biāo)分支自從公共基點(diǎn)后的commit:git diff master...contrib
查看共同父commit:git merge-base contrib master
展示修改:git diff
只合并特定節(jié)點(diǎn):git cherry-pick e43a6
準(zhǔn)備發(fā)布:git archive master --prefix='project/' | gzip > git describe master.tar.gz / git archive master --prefix='project/' --format=zip > git describe master.zip
查看遠(yuǎn)端所有分支锨亏,包括pull request:git ls-remote https://github.com/schacon/blink

Git工具

查看單個(gè)提交:

  $ git show 1c002dd4b536e7479fe34593e72e6c6c1819e53b
  $ git show 1c002dd4b536e7479f
  $ git show 1c002d

選擇父節(jié)點(diǎn):HEAD^
experiment上有但master上沒(méi)有的提交:git log master..experiment
refA或refB上有但是refC上沒(méi)有的提交:git log refA refB ^refC / git log refA refB --not refC
顯示master或者experiment中包含但不是兩者共有的提交:git log --left-right master...experiment
交互式暫存:git add -i
暫存工作:git stash / git stash push -m
刪除暫存:git stash drop
應(yīng)用并刪除暫存:git stash pop
查看所有暫存:git stash list
暫存并不重置工作區(qū):git stash --keep-index
同時(shí)暫存未跟蹤的文件:git stash -u
清理工作目錄:git clean -f -d
查找某個(gè)常量何時(shí)引入:git log -S ZLIB_BUF_MAX --oneline
查找zlib.c文件中g(shù)it_deflate_bound in the函數(shù)的每一次變更:git log -L :git_deflate_bound:zlib.c
修改最后一次提交:git commit --amend
修改前三個(gè)父節(jié)點(diǎn)的提交:git rebase -i HEAD~3
僅移動(dòng)HEAD:git reset --soft
移動(dòng)HEAD及索引:git reset --mixed (默認(rèn))
移動(dòng)HEAD并更新目錄:git reset --hard
squash提交

git reset --soft HEAD~2
git commit

回退記錄:git revert -m 1 HEAD
假合并:git merge -s ours mundo
查找bug引入源:git blame -L 69,82 Makefile
查看代碼原來(lái)在哪里:git blame -C -L 141,153 GITPackUpload.m
二分查找:

  $ git bisect start
  $ git bisect bad
  $ git bisect good v1.0

打包分支:git bundle create repo.bundle HEAD master
克隆打包:git clone repo.bundle repo
打包c(diǎn)ommit:git bundle create commits.bundle master ^9a466c5
驗(yàn)證包:git bundle verify ../commits.bundle
查看包分支:git bundle list-heads ../commits.bundle
導(dǎo)入包內(nèi)容:git fetch ../commits.bundle master:other-master

自定義Git

查看git支持的選項(xiàng)列表:man git-config

Git內(nèi)部遠(yuǎn)離

.git目錄下的核心內(nèi)容:HEAD 文件、(尚待創(chuàng)建的)index 文件乾翔,和 objects 目錄反浓、refs 目錄辆雾。objects 目錄存儲(chǔ)所有數(shù)據(jù)內(nèi)容月劈;refs 目錄存儲(chǔ)指向數(shù)據(jù)(分支)的提交對(duì)象的指針猜揪;HEAD 文件指示目前被檢出的分支湿右;index 文件保存暫存區(qū)信息

數(shù)據(jù)對(duì)象

Git的數(shù)據(jù)對(duì)象有四種:blob文件對(duì)象、tree樹(shù)對(duì)象吭狡、commit提交對(duì)象和tag標(biāo)簽對(duì)象

文件對(duì)象

創(chuàng)建新文件并存儲(chǔ)入數(shù)據(jù)內(nèi)容數(shù)據(jù)庫(kù):

$ echo 'version 1' > test.txt
$ git hash-object -w test.txt

接著划煮,向文件里寫入新內(nèi)容,并再次將其存入數(shù)據(jù)庫(kù):

$ echo 'version 2' > test.txt
$ git hash-object -w test.txt
1f7a7a472abf3dd9643fd615f6da379c4acb3e3a

可以查看到不同的版本內(nèi)容被記錄下來(lái):

$ find .git/objects -type f
.git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a
.git/objects/83/baae61804e65cc73a7201a7252750c76066a30

現(xiàn)在可以把文件內(nèi)容恢復(fù)到某個(gè)版本:

$ git cat-file -p 83baae61804e65cc73a7201a7252750c76066a30 > test.txt
$ cat test.txt
version 1
$ git cat-file -p 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a > test.txt
$ cat test.txt
version 2

樹(shù)對(duì)象

一個(gè)樹(shù)對(duì)象包含了一條或多條樹(shù)對(duì)象記錄(tree entry)俐载,每條記錄含有一個(gè)指向數(shù)據(jù)對(duì)象或者子樹(shù)對(duì)象的 SHA-1 指針挖炬,以及相應(yīng)的模式状婶、類型、文件名信息:

$ git cat-file -p master^{tree}
100644 blob a906cb2a4a904a152e80877d4088654daad0c859      README
100644 blob 8f94139338f9404f26296befa88755fc2598c289      Rakefile
040000 tree 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0      lib
$ git cat-file -p 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0
100644 blob 47c6340d6459e05787f644c2447d2595f5d3a54b      simplegit.rb

為創(chuàng)建一個(gè)樹(shù)對(duì)象钓猬,首先需要通過(guò)暫存一些文件來(lái)創(chuàng)建一個(gè)暫存區(qū)

git update-index --add --cacheinfo 100644 83baae61804e65cc73a7201a7252750c76066a30 test.txt

將暫存取寫入樹(shù)對(duì)象

$ git write-tree
d8329fc1cc938780ffdd9f94e0d364e0ea74f579
$ git cat-file -p d8329fc1cc938780ffdd9f94e0d364e0ea74f579
100644 blob 83baae61804e65cc73a7201a7252750c76066a30      test.txt

提交對(duì)象

提交對(duì)象包含了一個(gè)頂層樹(shù)對(duì)象敞曹,代表當(dāng)前項(xiàng)目快照:

$ echo 'first commit' | git commit-tree d8329f
fdf4fc3344e67ab068f836878b6c4951e3b15f3d
$ git cat-file -p fdf4fc3
tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579
author Scott Chacon <schacon@gmail.com> 1243040974 -0700
committer Scott Chacon <schacon@gmail.com> 1243040974 -0700

first commit

創(chuàng)建另外兩個(gè)提交對(duì)象异雁,格子飲用上一個(gè)提交:

$ echo 'second commit' | git commit-tree 0155eb -p fdf4fc3
cac0cab538b970a37ea1e769cbbde608743bc96d
$ echo 'third commit'  | git commit-tree 3c4e9c -p cac0cab
1a410efbd13591db07496601ebc7a059dd55cfe9

這就是每次我們運(yùn)行 git add 和 git commit 命令時(shí)僧须, Git 所做的實(shí)質(zhì)工作——將被改寫的文件保存為數(shù)據(jù)對(duì)象担平,更新暫存區(qū)暂论,記錄樹(shù)對(duì)象取胎,最后創(chuàng)建一個(gè)指明了頂層樹(shù)對(duì)象和父提交的提交對(duì)象闻蛀。 這三種主要的 Git 對(duì)象——數(shù)據(jù)對(duì)象觉痛、樹(shù)對(duì)象薪棒、提交對(duì)象——最初均以單獨(dú)文件的形式保存在 .git/objects 目錄下

標(biāo)簽對(duì)象

標(biāo)簽對(duì)象通常指向一個(gè)提交對(duì)象俐芯,而不是一個(gè)樹(shù)對(duì)象吧史。 它像是一個(gè)永不移動(dòng)的分支引用——永遠(yuǎn)指向同一個(gè)提交對(duì)象扣蜻,只不過(guò)給這個(gè)提交對(duì)象加上一個(gè)更友好的名字罷了莽使》技。可以像這樣創(chuàng)建一個(gè)輕量標(biāo)簽:

$ git update-ref refs/tags/v1.0 cac0cab538b970a37ea1e769cbbde608743bc96d

若要?jiǎng)?chuàng)建一個(gè)附注標(biāo)簽亿笤,Git 會(huì)創(chuàng)建一個(gè)標(biāo)簽對(duì)象,并記錄一個(gè)引用來(lái)指向該標(biāo)簽對(duì)象汪榔,而不是直接指向提交對(duì)象。 可以通過(guò)創(chuàng)建一個(gè)附注標(biāo)簽來(lái)驗(yàn)證這個(gè)過(guò)程(-a 選項(xiàng)指定了要?jiǎng)?chuàng)建的是一個(gè)附注標(biāo)簽):

$ git tag -a v1.1 1a410efbd13591db07496601ebc7a059dd55cfe9 -m 'test tag'
$ cat .git/refs/tags/v1.1
9585191f37f7b0fb9444f35a9bf50de191beadc2
$ git cat-file -p 9585191f37f7b0fb9444f35a9bf50de191beadc2
object 1a410efbd13591db07496601ebc7a059dd55cfe9
type commit
tag v1.1
tagger Scott Chacon <schacon@gmail.com> Sat May 23 16:48:58 2009 -0700

test tag

refs引用

引用是一個(gè)文件來(lái)保存 SHA-1 值燃领,并給文件起一個(gè)簡(jiǎn)單的名字猛蔽,然后用這個(gè)名字指針來(lái)替代原始的 SHA-1 值区岗。

git update-ref refs/heads/master 1a410efbd13591db07496601ebc7a059dd55cfe9

這基本就是Git分支的本質(zhì)凉泄,一個(gè)指向某一系列提交之首的指針或引用:

git update-ref refs/heads/test cac0ca

HEAD

HEAD 文件是一個(gè)符號(hào)引用(symbolic reference)胀糜,指向目前所在的分支教藻。 所謂符號(hào)引用括堤,意味著它并不像普通引用那樣包含一個(gè) SHA-1 值——它是一個(gè)指向其他引用的指針讥电。當(dāng)我們執(zhí)行 git commit 時(shí)恩敌,該命令會(huì)創(chuàng)建一個(gè)提交對(duì)象纠炮,并用 HEAD 文件中那個(gè)引用所指向的 SHA-1 值設(shè)置其父提交字段

$ cat .git/HEAD
ref: refs/heads/master
$ git symbolic-ref HEAD
refs/heads/master
$ git symbolic-ref HEAD refs/heads/test
$ cat .git/HEAD
ref: refs/heads/test

Git包文件

Git 最初向磁盤中存儲(chǔ)對(duì)象時(shí)所使用的格式被稱為“松散(loose)”對(duì)象格式。 但是灯蝴,Git 會(huì)時(shí)不時(shí)地將多個(gè)這些對(duì)象打包成一個(gè)稱為“包文件(packfile)”的二進(jìn)制文件恢口,以節(jié)省空間和提高效率。 當(dāng)版本庫(kù)中有太多的松散對(duì)象穷躁,或者你手動(dòng)執(zhí)行 git gc 命令耕肩,或者你向遠(yuǎn)程服務(wù)器執(zhí)行推送時(shí),Git 都會(huì)這樣做折砸。Git 打包對(duì)象時(shí)看疗,會(huì)查找命名及大小相近的文件,并只保存文件不同版本之間的差異內(nèi)容睦授。 你可以查看包文件,觀察它是如何節(jié)省空間的摔寨。 git verify-pack 這個(gè)底層命令可以讓你查看已打包的內(nèi)容删顶。

引用規(guī)格

引用規(guī)格的格式由一個(gè)可選的 + 號(hào)和緊隨其后的 <src>:<dst> 組成季惩,其中 <src> 是一個(gè)模式(pattern),代表遠(yuǎn)程版本庫(kù)中的引用;<dst> 是那些遠(yuǎn)程引用在本地所對(duì)應(yīng)的位置嫡意。 + 號(hào)告訴 Git 即使在不能快進(jìn)的情況下也要(強(qiáng)制)更新引用促煮∽迹可在.git/config文件中配置:

[remote "origin"]
url = https://github.com/schacon/simplegit-progit
fetch = +refs/heads/*:refs/remotes/origin/* 
push = refs/heads/master:refs/heads/qa/master

數(shù)據(jù)恢復(fù)

reset后找回丟失的commit痹仙,并基于丟失的提交創(chuàng)建分支

git reflog
git branch recover-branch ab1afef

找回丟失的分支

git fsck --full

git庫(kù)刪除大的文件記錄

//查找最大的文件
git verify-pack -v .git/objects/pack/pack-29…69.idx \
  | sort -k 3 -n \
  | tail -3
//顯示blob對(duì)應(yīng)的文件
$ git rev-list --objects --all | grep 82c99a3
82c99a3e86bb1267b236a4b6eff7868d97489af1 git.tgz
//查找包含這個(gè)blob的commit
git log --oneline --branches -- git.tgz
//重寫commit恩溅,從某個(gè)提交之后的所有commit中刪除對(duì)應(yīng)的blob
git filter-branch --index-filter \
  'git rm --ignore-unmatch --cached git.tgz' -- --all
rm -Rf .git/refs/original
rm -Rf .git/logs/
git gc
//移除不可引用的blob
git prune
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌昧甘,老刑警劉巖常侦,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件心剥,死亡現(xiàn)場(chǎng)離奇詭異畔柔,居然都是意外死亡枚粘,警方通過(guò)查閱死者的電腦和手機(jī)暴凑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)腿宰,“玉大人,你說(shuō)我怎么就攤上這事亦渗×勺埃” “怎么了昔搂?”我有些...
    開(kāi)封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵蟀给,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我响蕴,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任瘦穆,我火速辦了婚禮住涉,結(jié)果婚禮上毙芜,老公的妹妹穿的比我還像新娘展辞。我一直安慰自己扣唱,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布旭咽。 她就那樣靜靜地躺著,像睡著了一般癌蚁。 火紅的嫁衣襯著肌膚如雪努释。 梳的紋絲不亂的頭發(fā)上饿自,一...
    開(kāi)封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音炬搭,去河邊找鬼巍佑。 笑死,一個(gè)胖子當(dāng)著我的面吹牛苛预,可吹牛的內(nèi)容都是我干的句狼。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼热某,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼腻菇!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起昔馋,我...
    開(kāi)封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤筹吐,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后秘遏,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體丘薛,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年邦危,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了洋侨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片舍扰。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖希坚,靈堂內(nèi)的尸體忽然破棺而出边苹,到底是詐尸還是另有隱情,我是刑警寧澤裁僧,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布个束,位于F島的核電站,受9級(jí)特大地震影響聊疲,放射性物質(zhì)發(fā)生泄漏茬底。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一获洲、第九天 我趴在偏房一處隱蔽的房頂上張望阱表。 院中可真熱鬧,春花似錦昌妹、人聲如沸捶枢。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)烂叔。三九已至,卻和暖如春固歪,著一層夾襖步出監(jiān)牢的瞬間蒜鸡,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工牢裳, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留逢防,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓蒲讯,卻偏偏與公主長(zhǎng)得像忘朝,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子判帮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容