git init 創建repository
git add readme.txt git add命令實際上就是把要提交的所有修改放到暫存區(Stage)
add所有文件:git add .
add並rm所有:git add -A
提交modify和rm(新加的文件不會自動提交):git commit -a
git commit -m "log" 提交到master,添加log內容
git status 查看repository 狀態
git diff readme.txt 查看修改內容
git log (--prety=oneline) 查看log,后面參數可選
git reset --hard HEAD^ 回退上個版本(HEAD指向master的指針,^個數表示上幾個版本)
git reset --hard HEAD~100 回退n個版本
git reset --hard 3628164 回退到commit為3628164版本
git reflog 查看每一次命令
git checkout --readme.txt 把readme.txt文件在工作區的修改全部撤銷
這里有兩種情況:
一種是readme.txt自修改后還沒有被放到暫存區,現在,撤銷修改就回到和版本庫一模一樣的狀態;
一種是readme.txt已經添加到暫存區后,又作了修改,現在,撤銷修改就回到添加到暫存區后的狀態。
git checkout -- file命令中的“--”很重要,沒有“--”,就變成了“創建一個新分支”的命令
git reset HEAD readme.txt 可以把暫存區的修改撤銷掉(unstage),重新放回工作區
git rm readme.txt 從版本庫中刪除文件
git checkout -- readme.txt 如果在文件管理器中誤刪了文件,因為版本庫里還有呢,可以用這句恢復
關聯一個遠程庫,使用命令git remote add origin https://github.com/HelloGabo/MyUnityTest.git
關聯后,使用命令git push -u origin master第一次推送master分支的所有內容
每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改
克隆repository。創建一個空的repository,然后用命令
git clone https://github.com/HelloGabo/gitskills.git
將現在的repository克隆進去
分支:
查看分支:git branch
創建分支:git branch name
切換分支:git checkout name
創建+切換分支:git checkout -b name
合並某分支到當前分支:git merge name(Fast forward模式,這種模式下刪除分支后,會丟失分支信息)
-no-ff參數,表示禁用“Fast forward” 會在merge時生成一個新的commit,這樣,從分支歷史上就可以看出分支信息。
git merge --no-ff -m "merge with no-ff" dev
刪除分支:git branch -d name
git branch -D branch-name 強行刪除分支(當在分支上修改后,不想並入其他分支,想刪掉,就要強行刪除)
解決分支合並產生的沖突:
手動修改沖突后提交就行
git log --graph 命令可以看到分支合並圖
eg:git log --graph --pretty=oneline --abbrev-commit
當你接到一個修復一個代號101的bug的任務時,很自然地,你想創建一個分支issue -101來修復它,但是,等等,當前正在dev上進行的工作還沒有提交
stash功能,可以把當前工作現場“儲藏”起來,等以后恢復現場后繼續工作:git stash(有修改還沒add並commit的時候調用后,現場保留,分支清空)
git stash list命令查看工作現場
恢復有兩個辦法:
一是用git stash apply恢復,但是恢復后,stash內容並不刪除,你需要用git stash drop來刪除;
另一種方式是用git stash pop,恢復的同時把stash內容也刪了
查看遠程庫的信息,用git remote
git remote -v顯示更詳細的信息
$ git remote -v
origin https://github.com/HelloGabo/MyUnityTest.git (fetch) 抓取
origin https://github.com/HelloGabo/MyUnityTest.git (push) 推送
顯示了可以抓取和推送的origin的地址。如果沒有推送權限,就看不到push的地址
推送分支
推送分支,就是把該分支上的所有本地提交推送到遠程庫。推送時,要指定本地分支,這樣,Git就會把該分支推送到遠程庫對應的遠程分支上:
git push origin master
如果要推送其他分支,比如dev,就改成:
git push orgin dev
抓取分支
小伙伴要在dev分支上開發,就必須創建遠程origin的dev分支到本地,於是他用這個命令創建本地dev分支:
git checkout -b dev origin/dev
現在,就可以在dev上繼續修改,然后,時不時地把dev分支push到遠程:
git push origin dev
碰巧你也對同樣的文件作了修改,並試圖推送:推送失敗,因為你的小伙伴的最新提交和你試圖推送的提交有沖突
先用git pull把最新的提交從origin/dev抓下來,然后,在本地合並,解決沖突,再推送
git pull
失敗了,原因是沒有指定本地dev分支與遠程origin/dev分支的鏈接,根據提示,設置dev和origin/dev的鏈接:
git branch --set-upstream dev origin/dev
再pull就行了,但合並會有沖突。需要手動解決
標簽管理
發布一個版本時,我們通常先在版本庫中打一個標簽,這樣,就唯一確定了打標簽時刻的版本。將來無論什么時候,取某個標簽的版本,就是把那個打標簽的時刻的歷史版本取出來。所以,標簽也是版本庫的一個快照。
Git的標簽雖然是版本庫的快照,但其實它就是指向某個commit的指針(跟分支很像對不對?但是分支可以移動,標簽不能移動),所以,創建和刪除標簽都是瞬間完成的。
創建標簽
切換到需要打標簽的分支上git checkout dev
1、敲命令git tag name就可以打一個新標簽:git tag v1.0
2、git tag查看所有標簽
默認標簽是打在最新提交的commit上的。有時候,如果忘了打標簽,比如,現在已經是周五了,但應該在周一打的標簽沒有打,怎么辦?
方法是找到歷史提交的commit id,然后打上就可以了:
git log --pretty=oneline --abbrev-commit
對應的commit id是“ef51d63”,敲入命令git tag v0.9 ef51d63
3、可以用git show tagname查看標簽信息:git show v0.9
4、可以創建帶有說明的標簽,用-a指定標簽名,-m指定說明文字:
git tag -a v0.1 -m "version 0.1 released" 02172e4
5、可以通過-s用私鑰簽名一個標簽:git tag -s v0.2 -m "signed version 0.2 released" a8093be
簽名采用PGP簽名,因此,必須首先安裝gpg(GnuPG),如果沒有找到gpg,或者沒有gpg密鑰對,就會報錯
用命令git show tagname可以看到PGP簽名信息
用PGP簽名的標簽是不可偽造的,因為可以驗證PGP簽名。驗證簽名的方法比較復雜
操作標簽
標簽打錯了,也可以刪除:git tag -d v1.0
推送某個標簽到遠程,使用命令git push origin tagname:
一次性推送全部尚未推送到遠程的本地標簽:git push origin --tags
從遠程刪除。刪除命令也是git push origin :refs/tags/tagname
忽略特殊文件
有些時候,你必須把某些文件放到Git工作目錄中,但又不能提交它們,比如保存了數據庫密碼的配置文件啦,等等,每次git status都會顯示“Untracked files ...”
這個問題解決起來也很簡單,在Git工作區的根目錄下創建一個特殊的.gitignore文件,然后把要忽略的文件名填進去,Git就會自動忽略這些文件
不需要從頭寫.gitignore文件,GitHub已經為我們准備了各種配置文件,只需要組合一下就可以使用了。所有配置文件可以直接在線瀏覽:https://github.com/github/gitignore
最后一步就是把.gitignore也提交到Git
比如,忽略Python編譯產生的.pyc、.pyo、dist等文件或目錄:
# Python:
*.py[cod]
*.so
*.egg
*.egg-info
dist
build
使用Windows的童鞋注意了,如果你在資源管理器里新建一個.gitignore
文件,它會非常弱智地提示你必須輸入文件名,但是在文本編輯器里“保存”或者“另存為”就可以把文件保存為.gitignore
了。
Git 中的文件忽略
1. 共享式忽略新建 .gitignore 文件,放在工程目錄任意位置即可。.gitignore 文件可以忽略自己。忽略的文件,只針對未跟蹤文件有效,對已加入版本庫的文件無效。
2. 獨享式忽略針對具體版本庫 :.git/info/exclude針對本地全局: git config --global core.excludefile ~/.gitignore
忽略的語法規則:
(#)表示注釋
(*) 表示任意多個字符;
(?) 代表一個字符;
([abc]) 代表可選字符范圍
如果名稱最前面是路徑分隔符 (/) ,表示忽略的該文件在此目錄下。
如果名稱的最后面是 (/) ,表示忽略整個目錄,但同名文件不忽略。
通過在名稱前面加 (!) ,代表不忽略。
例子如下:
# 這行是注釋
*.a # 忽略所有 .a 偉擴展名的文件
!lib.a # 但是 lib.a 不忽略,即時之前設置了忽略所有的 .a
/TODO # 只忽略此目錄下 TODO 文件,子目錄的 TODO 不忽略
build/ # 忽略所有的 build/ 目錄下文件
doc/*.txt # 忽略如 doc/notes.txt, 但是不忽略如 doc/server/arch.txt
配置別名
如果敲git st就表示git status那就簡單多了
1、只需要敲一行命令,告訴Git,以后st就表示status:git config --global alias.st status
-2、-global參數是全局參數,也就是這些命令在這台電腦的所有Git倉庫下都有用。
3、命令git reset HEAD file可以把暫存區的修改撤銷掉(unstage),重新放回工作區。既然是一個unstage操作,就可以配置一個unstage別名:
git config --global alias.unstage 'reset HEAD'
敲入命令:git unstage test.py
實際上Git執行的是:git reset HEAD test.py
4、配置一個git last,讓其顯示最后一次提交信息:git config --global alias.last 'log -l'
用git last就能顯示最近一次的提交
甚至還有人喪心病狂地把lg配置成了:
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
搭建git服務器
搭建Git服務器需要准備一台運行Linux的機器,強烈推薦用Ubuntu或Debian,這樣,通過幾條簡單的apt命令就可以完成安裝。
假設你已經有sudo權限的用戶賬號,下面,正式開始安裝。
第一步,安裝git:sudo apt-get install git
第二步,創建一個git用戶,用來運行git服務:sudo adduser git
第三步,創建證書登錄:
收集所有需要登錄的用戶的公鑰,就是他們自己的id_rsa.pub文件,把所有公鑰導入到/home/git/.ssh/authorized_keys文件里,一行一個。
第四步,初始化Git倉庫:
先選定一個目錄作為Git倉庫,假定是/srv/sample.git,在/srv目錄下輸入命令:sudo git init --bare sample.git
Git就會創建一個裸倉庫,裸倉庫沒有工作區,因為服務器上的Git倉庫純粹是為了共享,所以不讓用戶直接登錄到服務器上去改工作區,並且服務器上的Git倉庫通常都以.git結尾。然后,把owner改為git:
sudo chown -R git:git sample.git
第五步,禁用shell登錄:
出於安全考慮,第二步創建的git用戶不允許登錄shell,這可以通過編輯/etc/passwd文件完成。找到類似下面的一行:
git:x:1001:1001,,,:/home/git:/bin/bash
改為:
git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell
這樣,git用戶可以正常通過ssh使用git,但無法登錄shell,因為我們為git用戶指定的git-shell每次一登錄就自動退出。
第六步,克隆遠程倉庫:
現在,可以通過git clone命令克隆遠程倉庫了,在各自的電腦上運行:
git clone git@server:/srv/sample.git
剩下的推送就簡單了
管理公鑰
如果團隊很小,把每個人的公鑰收集起來放到服務器的/home/git/.ssh/authorized_keys文件里就是可行的。如果團隊有幾百號人,就沒法這么玩了,這時,可以用Gitosis來管理公鑰。
這里我們不介紹怎么玩Gitosis了,幾百號人的團隊基本都在500強了,相信找個高水平的Linux管理員問題不大。
管理權限
有很多不但視源代碼如生命,而且視員工為竊賊的公司,會在版本控制系統里設置一套完善的權限控制,每個人是否有讀寫權限會精確到每個分支甚至每個目錄下。因為Git是為Linux源代碼托管而開發的,所以Git也繼承了開源社區的精神,不支持權限控制。不過,因為Git支持鈎子(hook),所以,可以在服務器端編寫一系列腳本來控制提交等操作,達到權限控制的目的。Gitolite就是這個工具。
國外網友制作的Git Cheat Sheet,建議打印出來備用:
Git的官方網站:http://git-scm.com,英文自我感覺不錯的童鞋,可以經常去官網看看