# git 操作跟觀念 ## 最重要的concept - 所有紀錄檔案都可以在.git底下找到 - <font color="#f00">head決定現在的位置,head跟branch一樣都是一個指針指到某一個commit,head決定現在的branch在哪</font> - <font color="#f00">checkout回去到某一個commit,很容易發生斷頭,若想在某一次commit作更改,記得要開一個branch並且checkout過去來紀錄</font> - info底下有一個exclude檔案,功用類似.gitignore,但不會push到遠端被別人看到你阻擋哪些東西上傳到遠端 - objects存放各個object的地方 - branchs紀錄branch - refs放heads跟tag,heads此資料夾底下放各個branch的head branch就像是一個tag連接在commit身上而已,但跟一般tag不同的是當你在此branch上commit時,branch會跟著你的commit前進 而相對於branch,tag單存是跟某一個commit綁在一起的,並不會跟著commit往前而有所變動 ### git 儲存方式 - git並不是利用diff的方式來紀錄每一個commit,而是針對每一個commit裡有跟動過的檔案,自己額外會在作sha壓縮並且存放在.git/object底下 - 當檔案太大或有commit推到遠端的時候,git才會利用diff的方式對資料進行壓縮,減少空間利用 ### 查看objects 可以利用 ```shell= git cat-file -p ${sha value} #可以得到裡面的value git cat-file -t ${sha value} #可以得到所屬型態 ``` .git/objects/底下會使用前兩個sha的value當作資料夾名稱,裡面檔案名稱則是剩下的sha value,因此當你要得到sha value,必須將資料夾名稱跟此資料夾中的檔案名稱相加起來 ### 4 git type 下面這幾個type都紀錄在.git/objects/底下 - blob:物件內容 - tree:資料夾,內容會指到資料夾裡面的物件(可能有多個物件,故此檔案可能有多行) - commit:也是一個檔案會指到所有跟此commit有關的檔案 ***指到的意思:在檔案中會存著這些資料的sha value - tag:針對某一個commit給一個標籤 ### tag <font color="#f00">常使用在設立某一個里程碑</font> ```shell= #列出所有標籤 git tag -l "v1.8.5*" #針對現在這個commit #big treasure只是一個tag,{$commit content}是commit內容 git tag -a big_treasure -m {{$commit content} ex:"這個commit真棒"} #針對過去的commit貼標籤 git tag -a v1.2 9fceb02 #將tag貼到遠端 git push origin v1.5 #將所有tags貼到遠端 git push origin --tags #在某個標籤上開分支 git checkout -b version2 v2.0.0 ``` ### index index就是save buffer(緩衝區,在add跟commit之間) 已經add但還沒commit之間會有一個buffer存放準備已經紀錄的資料 可以利用git ls-files查看已經紀錄哪些file進去 ### others - 當檔案為空的時候,"git add某個空的檔案"此指令並不會在.git/objects/下面再新增新的資料夾 - head可以利用@代替 - head前一個commit可以使用此符號@^作代替 ## 回到merge,rebase(危險操作)之前的狀態 <font color="#f00">如果才剛merge或rebase可以使用</font> ORIG_HEAD是在做merge或rebase之前,git會先把head的狀態存在這個到ORIG_HEAD 因此可以利用此方法回溯到危險動作之前的狀態 ```shell= git reset ORIG_HEAD --hard ``` ### 想修改最新一次的commit 名稱 ```shell= git commit --amend -m "xxxx" ``` <font color="#f00">注意:對於不同branch,最新的commit都算是自己branch上的</font> ### branch ```shell= git branch ${name} #checkout到那個branch git checkout ${name} #delete this branch git branch ${name} -d #在當前此branch merge 其他的branch git merge ${branch name} ``` ### git stash 有時會不想commmit,但必須立馬切換到某一個commit,這時可以使用stash方式暫時把修改的東西暫存起來 ```shell= #存到stash stack裡面 git stash #列出所有stash的紀錄 git stash list #pop出,2換成自己要的數字 git stash pop stash@{2} #確定不要的 git stash drop stash@{0} #這個跟pop不一樣的地方在於他不會從stash stack裡刪除,但pop會,所以stack裡面還會有一份 git stash apply stash@{0} ``` ### calculate sha value ```shell= cat ${filepath} | git hash-object --stdin ``` ### git alias ``` #put this code on ~/.gitconfig [alias] ll = log --graph --pretty=format:\"%h <%an> %ar%n comment: %s%n\" la = log --graph --oneline --all ls = log --graph --oneline ``` ### log 顯示所有commit ```shell= git log --oneline ``` ### diff ```shell= #比對兩個commit git diff ${commit id} ${commit id} #比對目前目前HEAD所指的這個commit之間跟此commit id之間的差異 git diff ${commit id} #比對工作目錄跟暫存區之間的差異 git diff #目前暫存區與HEAD所指向的那個commit之間的差異。 git diff --cached ``` ### pull ```shell= git add . git commit -m "自訂的檔案名稱" git pull oringin master ``` ### push ```shell= git add . git commit -m "自訂的檔案名稱" git push oringin master ``` ### 想要將某一個東西(或修改)加入到最新的commit 有時會忘記有些東西要加入到前一次commit中(最新的commit),這時可以利用下面此方法加進去 ```shell= git add ${filepath} #no-edit代表不要改變git commit 訊息 git commit --amend --no-edit ``` ###### tags: `git`