Git超級簡明手冊
版本控制系統的歷史
版本控制系統,用于協調多個開發者之間的開發。
- CVS----使用文件鎖。如果一個人鎖定了一個文件,那么其他人就無法修改該文件。
- SVN----集中式版本控制系統。提交之前需要先拉下服務器上的版本,修改沖突后再提交。
- 建立分支依靠本地目錄復制。空間利用率低。
- Mercurial----分布式版本控制系統。
- Git----免費的分布式版本控制系統。在BitKeeper不再免費提供給linux項目使用后開發。本地有完整的備份。使用軟鏈接減少內容。
- 建立分支依靠軟鏈接。空間利用率高。 </ul>
- master
默認是master分支。
</ul>
創建git項目
要對現有的某個項目開始用 Git 管理,只需到此項目所在的目錄,執行: $ git init 初始化后,在當前目錄下會出現一個名為 .git 的目錄,所有 Git 需要的數據和資源都存放在這個目錄 中。不過目前,僅僅是按照既有的結構框架初始化好了里邊所有的文件和目錄,但我們還沒有開始跟蹤管理項 目中的任何一個文件。(在第九章我們會詳細說明剛才創建的 .git 目錄中究竟有哪些文件,以及都起些什么 作用。) 如果當前目錄下有幾個文件想要納入版本控制,需要先用 git add 命令告訴 Git 開始對這些文件進行跟 蹤,然后提交: $ git add *.c $ git add README $ git commit -m 'initial project version' 稍后我們再逐一解釋每條命令的意思。不過現在,你已經得到了一個實際維護著若干文件的 Git 倉庫。
共享git項目
上面,我們已經在本地創建了一個git項目。但有一個問題,其他用戶如何訪問我們的這個git項目?
純git倉庫
開始架設 Git 服務器的時候,需要把一個現存的倉庫導出為新的純倉庫——不包含當前工作目錄的倉庫。 方法非常直截了當。 把一個倉庫克隆為純倉庫,可以使用 clone 命令的 .git 結尾, 如下: $ git clone --bare my_project my_project.git Initialized empty Git repository in /opt/projects/my_project.git/
共享文件夾
最簡單的方法,是使用NFS/Samba這樣的共享文件系統。 git clone /opt/git/project.git 或者: git clone file:///opt/git/project.git
git clone user@server:project.git
共享用戶
可以給每一個用戶分配一個git所在計算機上的服務器用戶賬戶,然后使用ssh協議訪問。 git clone ssh://user@server:project.git
http服務器
$ cd /var/www/htdocs/ $ git clone --bare /path/to/git_project gitproject.git $ cd gitproject.git $ mv hooks/post-update.sample hooks/post-update $ chmod a+x hooks/post-update
在本例中,我們使用了 Apache 設定中常用的 /var/www/htdocs 路徑,不過你可以使用任何靜態 web 服務 ——把純倉庫放在它的目錄里就行了。
用戶可以通過下面的命令來拉取git項目。 git clone http://example.com/gitproject.git 但用戶無法通過http提交代碼。 http協議也可以提交git代碼。但需要假設復雜的webdav服務器。
部署到Github網站
上面各種部署git服務器的方法,都很瑣碎,很麻煩。 實際上,現在已經有了不少提供git服務托管的平臺。最大的就是github。 https://github.com/explore
github上面有部署了很多開源項目和閉源項目。 github對于開源項目是免費的。對于閉源項目則是收費的。考慮到維護一個git服務器并在internet上可用的成本因素,把公司商業項目存放到github上也是劃算的。
部署到gitlab上
公司商業項目,部署到github上,會有一些費用產生。另外,由于代碼在github公司的機房上,可能會存在安全問題。 一些公司因此希望把git服務器架設在公司內的服務器上。 gitlab項目,是github的開源選項。用戶可以自己搭建gitlab服務器。 gitlab擁有和github一樣的完備功能。包括,查看提交,下載文件,wiki,bug和功能跟蹤,合并請求等。 除了使用gitlab站點假設git服務器外,還可以把它用作文件、照片、錄像等的共享站點。wiki站點。也可以把issue功能用作論壇。基本上可以滿足你的所有常用信息共享和交流的需要。限制你的只有你的想象力:) 在gitlab上部署項目很簡單。
在gitlab上新建一個git項目:
提交請求后,就會告訴你接下來怎么辦。
Command line instructions git config --global user.name "shendl" git config --global user.email "shendl@XXX.cn" mkdir test1 cd test1 git init touch README.md git add README.md git commit -m "first commit" git remote add origin git@gitlab.XXX.cn:shendl/test1.git
git push -u origin master cd existing_git_repo git remote add origin git@gitlab.XXX.cn:shendl/test1.git
git push -u origin master
使用http方式訪問,就是: http://gitlab.XXX.cn:80/shendl/test1.git
給項目添加用戶:
點擊左側的Settings->Members,可以添加用戶,并選擇用戶訪問權限。
生成ssh key并添加到gitlab服務器上,免除每次都要輸入密碼的麻煩
點擊右側的Profile Settings: 點擊ssh key:
可以添加ssh key到gitlab中。這樣,你就不需要每次輸入用戶名和密碼了。gitlab服務器會通過ssh key來認證用戶。
Ssh key的生成方法:
SSH SSH keys An SSH key allows you to establish a secure connection between your computer and GitLab. Before generating an SSH key, check if your system already has one by running cat ~/.ssh/id_rsa.pub. If you see a long string starting with ssh-rsa or ssh-dsa, you can skip the ssh-keygen step.
To generate a new SSH key, just open your terminal and use code below. The ssh-keygen command prompts you for a location and filename to store the key pair and for a password. When prompted for the location and filename, you can press enter to use the default. It is a best practice to use a password for an SSH key, but it is not required and you can skip creating a password by pressing enter. Note that the password you choose here can't be altered or retrieved. ssh-keygen -t rsa -C "shendl@XXX.cn" Use the code below to show your public key. cat ~/.ssh/id_rsa.pub Copy-paste the key to the 'My SSH Keys' section under the 'SSH' tab in your user profile. Please copy the complete key starting with ssh- and ending with your username and host. Use code below to copy your public key to the clipboard. Depending on your OS you'll need to use a different command: Windows: clip < ~/.ssh/id_rsa.pub Mac: pbcopy < ~/.ssh/id_rsa.pub GNU/Linux (requires xclip): xclip -sel clip < ~/.ssh/id_rsa.pub Deploy keys Deploy keys allow read-only access to multiple projects with a single SSH key. This is really useful for cloning repositories to your Continuous Integration (CI) server. By using deploy keys, you don't have to setup a dummy user account. If you are a project master or owner, you can add a deploy key in the project settings under the section 'Deploy Keys'. Press the 'New Deploy Key' button and upload a public SSH key. After this, the machine that uses the corresponding private key has read-only access to the project. You can't add the same deploy key twice with the 'New Deploy Key' option. If you want to add the same key to another project, please enable it in the list that says 'Deploy keys from projects available to you'. All the deploy keys of all the projects you have access to are available. This project access can happen through being a direct member of the project, or through a group. See def accessible_deploy_keys in app/models/user.rb for more information.
生成ssh key后,添加到gitlab中:
git常用技巧
好了,現在我們已經有了便于訪問的git服務器,大家可以一起協作使用git進行開發了。
git和http方式的區別
gitlab服務器,支持git和http兩種訪問協議。 如果使用http方式訪問,則每次都需要輸入gitlab的用戶名和密碼進行用戶身份認證。 如果使用git方式訪問,并且已經提交了ssh key到gitlab服務器,則無需輸入用戶名和密碼即可使用git。 另外,對于大文件,http訪問可能會上傳或者下載失敗。此時只能使用git方式。 git方式: git remote add origin git@10.10.100.47:shendl/test1.git http方式: git remote add origin http://gitlab.XXX.cn:80/shendl/test1.git
從git項目得到純代碼
我們要分發git項目的代碼時,不希望把git文件也一起發出去。這時可以使用如下命令: git archive master --prefix='project/' | gzip >git describe master.tar.gz master可以改成其他分支名。
生成用于部署服務器的純git項目
$ git clone --bare my_project my_project.git
添加.gitignore文件
在git項目的根目錄下,新建一個.gitignore文件,用于決定忽略添加一些本地文件到git服務器上。 git add .gitignore -f 把這個.gitignore文件添加到git服務器上。 臨時文件,編譯生成的文件,本地項目配置文件,不應該提交到git服務器上。否則會造成重復,還會影響其他用戶的開發環境。
添加文件到git版本控制下
git add README.md 我們可以使用 git add ./ 添加所有文件。
提交到本地git版本控制下
git commit -m "first commit" git commit -a 會彈出一個編輯器,讓你編寫注釋
提交本地改變到git遠程服務器上
git push -u origin master origin是遠程git服務器默認名。master是本地git的默認分支名。
Git push不會提交tag到服務器上,需要執行下列命令,才能把tag推送到服務器上。 git push --tags
拉取遠程服務器的最新改變到本地
git pull
查看本地倉庫的修改狀態
git status
查看提交
Git log 這里的log,就是 git commit -m "first commit" git commit -a 會彈出一個編輯器,讓你編寫注釋 中編寫的注釋
git log -p 查看每次提交的差異。
查看標簽
git tag
添加標簽
git tag -a v1.6.0-3 在當前提交上創建一個tag,并添加注釋
查看標簽詳情
git tag -v v1.0.0-2 object f94c91da7345153f7623eae82a253d40f6dc8832 type commit tag v1.0.0-2 tagger shendl shendl@XXX.cn 1443519901 +0800
版本v1.0.0-2 error: no signature found error: 不能校驗 tag 'v1.0.0-2'
你可以根據散列碼,找到對應的git log中的提交項目。
刪除本地標簽
git tag -d v1.7.0-11
推送本地標簽到遠程
git push --tags
刪除遠程標簽
如果遠程已經存在與本地同名的標簽但是內容不同,則推送會失敗。此時需要刪除遠程標簽。命令如下: git push origin --delete tag v1.7.0-11
得到版本號
git describe master v1.0.0-2 再做一次提交后,再次執行 git describe master v1.0.0-2-1-g438d372
v1.0.0-2-1是最近一次打的tag,438d372是最近一次提交的散列碼的前7位。通過這個版本號,可以找到對應的git的提交。 查看分支 git branch
創建并切換到新分支
git checkout -b test 切換到一個新分支 'test'
切換到已有的分支
git checkout master 切換到分支 'master' 您的分支與上游分支 'origin/master' 一致。
丟棄未提交的修改
有時,我們做了一些修改,最后發現修改錯了。我們希望直接丟棄這些修改。 git stash 文件會恢復到之前的狀態。 注意:只有git add file添加后的文件,commit之前的改變,才會被git stash丟棄
git stash pop 命令,可以恢復被丟棄的更改。
回滾到某個提交的狀態
Git log 查看提交歷史,找出對應的hash編碼 git checkout 438d372b1d07b1210add0c98af00f3f765553218 就可以回到該歷史狀態。
但此時已經不在任何分支中,因此無法提交代碼。 如果希望在這個狀態開始提交代碼,則需要使用 git branch -b branchName 在此基礎上創建一個新的分支。
回滾到某個tag的狀態
Git tag 查看提交 Git checkout tag名稱 其他和回滾到某個提交的語法一樣。
取消某次提交
Git log查看提交 git revert 1bb71333ca72f99158c7f1ea805fa70abc9416a7 這會進行一次新的提交,內容就是取消對應提交的內容。
再次git log,可以看到添加了一次新的提交。
回復到某次提交,并丟棄后續所有提交
Git log查看提交 git reset 1bb71333ca72f99158c7f1ea805fa70abc9416a7 這回回復到該提交的狀態,并丟棄后續所有提交。
再次git log,可以該提交后的log都沒了。 被刪除的內容,實際上被扔在了git stash中。 可以使用git stash pop命令,把刪除的內容恢復回來。
重命名文件
git mv old new
刪除文件
git rm file
Git子模塊
子模塊允許你將一個 Git 倉庫作為另一個 Git 倉庫的子目錄。 它能讓你將另一個倉庫克隆到自己的項目中,同時還保持提交的獨立。 git submodule add URL [localDir]
給項目添加一個子模塊 如 git submodule add git@10.10.100.47:shendl/qtCommon.git
或者 git submodule add git@10.10.100.47:shendl/qtCommon.git qtCommon 提交代碼后,項目就擁有了子模塊。 子模塊表現為項目的一個子目錄。 項目的git命令不會影響子模塊。 進入到子模塊,可以執行完整的git命令。
隨后需要 git add ./ git commit -a git push 推送這個更改到服務器。
其他客戶端 git clone URL 或者git pull 拉到源代碼,此時,子模塊目錄下沒有內容。 執行: git submodule init 會執行初始化子模塊 git submodule update 下載子模塊的最新源代碼到本地。 每次子模塊代碼更新時,需要執行git submodule update下載最新的源代碼到本地。或者也可以cd 子模塊目錄,然后執行git pull獲取源代碼。
注意: 子模塊,通常用來引用第三方項目的某一個穩定版本的代碼或者分支。 在子模塊中,最好不要修改代碼。而是另外作為一個獨立的git項目把該子模塊下載下來,進行開發和提交。 在包含子模塊的項目中,只執行git submodule update 命令下載最新的代碼。因為git submodule update命令會下載項目最新代碼并直接覆蓋掉本地代碼。因此不應該在子模塊中修改代碼。 如果一定要在子模塊中修改代碼,可以在子模塊中新建一個分支,在該獨立分支中開發,最后與項目代碼進行分支合并或者子樹合并。
gitTools
gitTools是一個開源項目,用于提供幫助簡化git日常使用的工具。
gitPullSubdir.py
gitPullSubdir.py是gitTools包中的一個實用工具程序。使用它可以遍歷指定目錄下所有子目錄,執行git pull,拉去最新代碼。使用這個工具,可以幫助你快速更新所有git項目。 gitPullSubdir.py -i XXX 遍歷拉取指定目錄下所有子目錄的git項目的最新源碼。
PS:本文pdf版本,可以在如下地址下載:Git超級簡明手冊pdf版