史上最全github使用方法:github入門到精通

GitHub詳細教程



1 Git詳細教程


1.1 Git簡介


1.1.1 Git是何方神聖?


Git是用C語言開發的分佈版本控制系統。版本控制系統能夠保留一個文件集合的歷史記錄,並能回滾文件集合到另外一個狀態(歷史記錄狀態)。另外一個狀態能夠是不一樣的文件,也能夠是不一樣的文件內容。舉個例子,你能夠將文件集合轉換到兩天以前的狀態,或者你能夠在生產代碼和實驗性質的代碼之間進行切換。文件集合每每被稱做是「源代碼」。在一個分佈版本控制系統中,每一個人都有一份完整的源代碼(包括源代碼全部的歷史記錄信息),並且能夠對這個本地的數據進行操做。分佈版本控制系統不須要一個集中式的代碼倉庫。html


當你對本地的源代碼進行了修改,你能夠標註他們跟下一個版本相關(將他們加到index中),而後提交到倉庫中來(commit)。Git保存了全部的版本信息,因此你能夠轉換你的源代碼到任何的歷史版本。你能夠對本地的倉庫進行代碼的提交,而後與其餘的倉庫進行同步。你可使用Git來進行倉庫的克隆(clone)操做,完整的複製一個已有的倉庫。倉庫的全部者能夠經過push操做(推送變動到別處的倉庫)或者Pull操做(從別處的倉庫拉取變動)來同步變動。git


Git支持分支功能(branch)。若是你想開發一個新的產品功能,你能夠創建一個分支,對這個分支的進行修改,而不至於會影響到主支上的代碼。github


Git提供了命令行工具;這個教程會使用命令行。你也能夠找到圖形工具,譬如與Eclipse配套的EGit工具,可是這些都不會在這個教程中進行描述。算法


1.1.2 重要的術語


Git 術語ubuntu

術語 定義
倉庫 一個倉庫包括了全部的版本信息、全部的分支和標記信息.
Repository 在Git中倉庫的每份拷貝都是完整的。倉庫讓你能夠從中
  取得你的工做副本。
  一個分支意味着一個獨立的、擁有本身歷史信息的代碼線
分支 (code line)。你能夠從已有的代碼中生成一個新的分支
Branches ,這個分支與剩餘的分支徹底獨立。默認的分支每每是叫
  master。用戶能夠選擇一個分支,選擇一個分支叫作
  checkout.
標記 一個標記指的是某個分支某個特定時間點的狀態。經過標
Tags 記,能夠很方便的切換到標記時的狀態,例如2009年1月25
  號在testing分支上的代碼狀態
提交 提交代碼後,倉庫會建立一個新的版本。這個版本能夠在
Commit 後續被從新得到。每次提交都包括做者和提交者,做者和
  提交者能夠是不一樣的人
URL URl用來標識一個倉庫的位置
  用來表示代碼的一個版本狀態。Git經過用SHA1 hash算法
修訂 表示的id來標識不一樣的版本。每個 SHA1 id都是160位長
Revision ,16進制標識的字符串.最新的版本能夠經過HEAD來獲取.
  以前的版本能夠經過"HEAD~1"來獲取,以此類推。


1.1.3 索引


Git 須要將代碼的變化顯示的與下一次提交進行關聯。舉個例子,若是你對一個文件繼續了修改,而後想將這些修改提交到下一次提交中,你必須將這個文件提交到索引中,經過git add file命令。這樣索引能夠保存全部變化的快照。安全


新增的文件老是要顯示的添加到索引中來。對於那些以前已經提交過的文件,能夠在commit命令中使用-a 選項達到提交到索引的目的。服務器


1.2 Git安裝


在Ubuntu上,你能夠經過apt來安裝git命令行工具網絡


sudo apt-get install git-core


對於其餘的Linux版本,請查看相關的軟件包安裝工具使用方法。msysgit項目提供了Windows版本的Git,地址是http://code.google.com/p/msysgit/併發


1.3 Git配置


你能夠在.gitconfig文件中防止git的全局配置。文件位於用戶的home目錄。上述已經提到每次提交都會保存做者和提交者的信息,這些信息均可以保存在全局配置中。後續將會介紹配置用戶信息、高亮顯示和忽略特定的文件。app


1.3.1 用戶信息


經過以下命令來配置用戶名和Email

git config --global user.name "Example Surname"

git config --global user.email "your.email@gmail.com"
# Set default so that all changes are always pushed to the repository
git config --global push.default "matching"


獲取Git配置信息,執行如下命令:

git config --list


1.3.2 高亮顯示

如下命令會爲終端配置高亮

git config --global color.status auto
git config --global color.branch auto


1.3.3 忽略特定的文件

能夠配置Git忽略特定的文件或者是文件夾。這些配置都放在.gitignore文件中。這個文件能夠存在於不一樣的文件夾中,能夠包含不一樣的文件匹配模式。爲了讓Git忽略bin文件夾,在主目錄下放置.gitignore文件,其中內容爲bin。

同時Git也提供了全局的配置,core.excludesfile。


1.3.4 使用.gitkeep來追蹤空的文件夾

Git會忽略空的文件夾。若是你想版本控制包括空文件夾,根據慣例會在空文件夾下放置.gitkeep文件。其實對文件名沒有特定的要求。一旦一個空文件夾下有文件後,這個文件夾就會在版本控制範圍內。


1.4 開始操做Git

後續將經過一個典型的Git工做流來學習。在這個過程當中,你會建立一些文件、建立一個本地的Git倉庫、提交你的文件到這個倉庫中。這以後,你會克隆一個倉庫、在倉庫之間經過pull和push操做來交換代碼的修改。註釋(以#開頭)解釋了命令的具體含義,讓咱們打開命令行開始操做吧。


1.4.1 建立內容

下面建立一些文件,它們會被放到版本控制之中

<span style="color: rgb(255, 127, 36);">#</span><span style="color: rgb(255, 127, 36);">Switch to home
</span><span style="color: rgb(176, 196, 222);">cd</span> ~/
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Create a directory
</span>mkdir ~/repo01
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Switch into it
</span><span style="color: rgb(176, 196, 222);">cd</span> repo01
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Create a new directory
</span>mkdir datafiles
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Create a few files
</span>touch test01
touch test02
touch test03
touch datafiles/data.txt
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Put a little text into the first file
</span>ls >test01


1.4.2 建立倉庫、添加文件和提交更改

每一個Git倉庫都是放置在.git文件夾下.這個目錄包含了倉庫的全部歷史記錄,.git/config文件包含了倉庫的本地配置。

如下將會建立一個Git倉庫,添加文件倒倉庫的索引中,提交更改。

<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Initialize the local Git repository
</span>git init
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Add all (files and directories) to the Git repository
</span>git add .
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Make a commit of your file to the local repository
</span>git commit -m <span style="color: rgb(255, 160, 122);">"Initial commit"</span>
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Show the log file
</span>git log


1.4.3 diff命令與commit更改

經過git diff命令,用戶能夠查看更改。經過改變一個文件的內容,看看gitdiff命令輸出什麼,而後提交這個更改到倉庫中

<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Make some changes to the file
</span><span style="color: rgb(176, 196, 222);">echo</span> <span style="color: rgb(255, 160, 122);">"This is a change"</span> > test01
<span style="color: rgb(176, 196, 222);">echo</span> <span style="color: rgb(255, 160, 122);">"and this is another change"</span> > test02

<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Check the changes via the diff command 
</span>git diff

<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Commit the changes, -a will commit changes for modified files
</span><span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">but will not add automatically new files
</span>git commit -a -m <span style="color: rgb(255, 160, 122);">"These are new changes"</span>


1.4.4 Status, Diff 和 Commit Log

下面會向你展現倉庫現有的狀態以及過往的提交歷史

<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Make some changes in the file
</span><span style="color: rgb(176, 196, 222);">echo</span> <span style="color: rgb(255, 160, 122);">"This is a new change"</span> > test01
<span style="color: rgb(176, 196, 222);">echo</span> <span style="color: rgb(255, 160, 122);">"and this is another new change"</span> > test02

<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">See the current status of your repository 
</span><span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">(which files are changed / new / deleted)
</span>git status
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Show the differences between the uncommitted files 
</span><span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">and the last commit in the current branch
</span>git diff

<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Add the changes to the index and commit
</span>git add . && git commit -m <span style="color: rgb(255, 160, 122);">"More chaanges - typo in the commit message"</span>

<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Show the history of commits in the current branch
</span>git log
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">This starts a nice graphical view of the changes
</span>gitk --all


1.4.5 更正提交的信息 - git amend

經過git amend命令,咱們能夠修改最後提交的的信息。上述的提交信息中存在錯誤,下面會修改這個錯誤。

git commit --amend -m "More changes - now correct"


1.4.6 刪除文件

若是你刪除了一個在版本控制之下的文件,那麼使用git add .不會在索引中刪除這個文件。須要經過帶-a選項的git commit命令和-A選項的git add命令來完成

<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Create a file and put it under version control
</span>touch nonsense.txt
git add . && git commit -m <span style="color: rgb(255, 160, 122);">"a new file has been created"</span>
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Remove the file
</span>rm nonsense.txt
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Try standard way of committing -> will not work 
</span>git add . && git commit -m <span style="color: rgb(255, 160, 122);">"a new file has been created"</span>
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Now commit with the -a flag
</span>git commit -a -m <span style="color: rgb(255, 160, 122);">"File nonsense.txt is now removed"</span>
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Alternatively you could add deleted files to the staging index via
</span>git add -A . 
git commit -m <span style="color: rgb(255, 160, 122);">"File nonsense.txt is now removed"</span>


1.5 遠端倉庫(remote repositories)


1.5.1 設置一個遠端的Git倉庫


咱們將建立一個遠端的Git倉庫。這個倉庫能夠存儲在本地或者是網絡上。


遠端Git倉庫和標準的Git倉庫有以下差異:一個標準的Git倉庫包括了源代碼和歷史信息記錄。咱們能夠直接在這個基礎上修改代碼,由於它已經包含了一個工做副本。可是遠端倉庫沒有包括工做副本,只包括了歷史信息。可使用–bare選項來建立一個這樣的倉庫。


爲了方便起見,示例中的倉庫建立在本地文件系統上

<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Switch to the first repository
</span><span style="color: rgb(176, 196, 222);">cd</span> ~/repo01
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">
</span>git clone --bare . ../remote-repository.git

<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Check the content, it is identical to the .git directory in repo01
</span>ls ~/remote-repository.git


1.5.2 推送更改到其餘的倉庫


作一些更改,而後將這些更改從你的第一個倉庫推送到一個遠端倉庫 


cd ~/repo01

echo "Hello, hello. Turn your radio on" > test01echo "Bye, bye. Turn your radio off" > test02

git commit -a -m "Some changes"

git push ../remote-repository.git


1.5.3 添加遠端倉庫


除了經過完整的URL來訪問Git倉庫外,還能夠經過git remote add命令爲倉庫添加一個短名稱。當你克隆了一個倉庫之後,origin表示所克隆的原始倉庫。即便咱們從零開始,這個名稱也存在。


<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Add ../remote-repository.git with the name origin
</span>git remote add origin ../remote-repository.git 

<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Again some changes
</span><span style="color: rgb(176, 196, 222);">echo</span> <span style="color: rgb(255, 160, 122);">"I added a remote repo"</span> > test02
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Commit
</span>git commit -a -m <span style="color: rgb(255, 160, 122);">"This is a test for the new remote origin"</span>
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">If you do not label a repository it will push to origin
</span>git push origin


1.5.4 顯示已有的遠端倉庫


經過如下命令查看已經存在的遠端倉庫

# Show the existing defined remote repositories
git remote


1.5.5 克隆倉庫

經過如下命令在新的目錄下建立一個新的倉庫

<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Switch to home
</span><span style="color: rgb(176, 196, 222);">cd</span> ~
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Make new directory
</span>mkdir repo02

<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Switch to new directory
</span>
<span style="color: rgb(176, 196, 222);">cd</span> ~/repo02
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Clone
</span>git clone ../remote-repository.git .


1.5.6 拉取(Pull)更改

經過拉取,能夠從其餘的倉庫中獲取最新的更改。在第二個倉庫中,作一些更改,而後將更改推送到遠端的倉庫中。而後第一個倉庫拉取這些更改

<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Switch to home
</span><span style="color: rgb(176, 196, 222);">cd</span> ~

<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Switch to second directory
</span><span style="color: rgb(176, 196, 222);">cd</span> ~/repo02
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Make changes
</span><span style="color: rgb(176, 196, 222);">echo</span> <span style="color: rgb(255, 160, 122);">"A change"</span> > test01
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Commit
</span>git commit -a -m <span style="color: rgb(255, 160, 122);">"A change"</span>
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Push changes to remote repository
</span><span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Origin is automatically maintained as we cloned from this repository
</span>git push origin
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Switch to the first repository and pull in the changes
</span><span style="color: rgb(176, 196, 222);">cd</span> ~/repo01
git pull ../remote-repository.git/
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Check the changes
</span>less test01


1.5.7 還原更改

若是在你的工做副本中,你建立了不想被提交的文件,你能夠丟棄它。

# Create a new file with content
touch test04
echo "this is trash" > test04

# Make a dry-run to see what would happen
# -n is the same as --dry-run 
git clean -n

# Now delete
git clean -f

你能夠提取老版本的代碼,經過提交的ID。git log命令能夠查看提交ID 

# Switch to home
cd ~/repo01
# Get the log
git log

# Copy one of the older commits and checkout the older revision via  譯者注:checkout 後加commit id就是把commit的內容複製到index和工做副本中 
git checkout commit_name


若是你還未把更改加入到索引中,你也能夠直接還原全部的更改

<span style="color: rgb(255, 127, 36);">#</span><span style="color: rgb(255, 127, 36);">Some nonsense change
</span><span style="color: rgb(176, 196, 222);">echo</span> <span style="color: rgb(255, 160, 122);">"nonsense change"</span> > test01
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Not added to the staging index. Therefore we can 
</span><span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">just checkout the old version
</span><span style="color: rgb(255, 127, 36);">#</span><span style="color: rgb(255, 127, 36);">譯者注:checkout後若是沒有commit id號,就是從index中拷貝數據到工做副本,不涉及commit部分的改變
</span>git checkout test01
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Check the result
</span>cat test01
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Another nonsense change
</span><span style="color: rgb(176, 196, 222);">echo</span> <span style="color: rgb(255, 160, 122);">"another nonsense change"</span> > test01
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">We add the file to the staging index
</span>git add test01
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Restore the file in the staging index
</span><span style="color: rgb(255, 127, 36);">#</span><span style="color: rgb(255, 127, 36);">譯者注:複製HEAD所指commit的test01文件到index中
</span>git reset HEAD test01
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Get the old version from the staging index
</span><span style="color: rgb(255, 127, 36);">#</span><span style="color: rgb(255, 127, 36);">譯者注:複製index中test01到工做副本中
</span>git checkout test01
<span style="color: rgb(255, 127, 36);">#</span><span style="color: rgb(255, 127, 36);">譯者注,以上兩條命令能夠合併爲git checkout HEAD test01
</span>
也能夠經過revert命令進行還原操做 

<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Revert a commit
</span>git revert commit_name


即便你刪除了一個未添加到索引和提交的文件,你也能夠還原出這個文件

<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Delete a file
</span>rm test01
<span style="color: rgb(255, 127, 36);"># </span><span style="color: rgb(255, 127, 36);">Revert the deletion
</span>git checkout test01


若是你已經添加一個文件到索引中,可是未提交。能夠經過git resetfile 命令將這個文件從索引中刪除

// Create a file
touch incorrect.txt
// Accidently add it to the index
git add .
// Remove it from the index
git reset incorrect.txt
// Delete the file
rm incorrect.txt


若是你刪除了文件夾且還沒有提交,能夠經過如下命令來恢復這個文件夾 。譯者注:即便已經提交,也能夠還原

git checkout HEAD -- your_dir_to_restore


譯者注:checkout和reset這兩個命令的含義是不一樣的,能夠參閱這篇文章http://marklodato.github.com/visual-git-guide/index-en.html


1.5.8 標記

Git可使用對歷史記錄中的任一版本進行標記。這樣在後續的版本中就能輕鬆的找到。通常來講,被用來標記某個發行的版本。能夠經過git tag命令列出全部的標記,經過以下命令來建立一個標記和恢復到一個標記

git tag version1.6 -m 'version 1.6'      
git checkout <tag_name>


1.6 分支、合併


1.6.1 分支


經過分支,能夠創造獨立的代碼副本。默認的分支叫master。Git消耗不多的資源就能建立分支。Git鼓勵開發人員多使用分支


下面的命令列出了全部的本地分支,當前所在的分支前帶有*號

git branch 


若是你還想看到遠端倉庫的分支,可使用下面的命令

git branch -a


能夠經過下面的命令來建立一個新的分支

# Syntax: git branch <name> <hash>
# <hash> in the above is optional 
# if not specified the last commit will be used
# If specified the corresponding commit will be used
git branch testing
# Switch to your new branch
git checkout testing
# Some changes
echo "Cool new feature in this branch" > test01
git commit -a -m "new feature"
# Switch to the master branch
git checkout master
# Check that the content of test01 is the old one
cat test01


1.6.2 合併


經過Merge咱們能夠合併兩個不一樣分支的結果。Merge經過所謂的三路合併來完成。分別來自兩個分支的最新commit和兩個分支的最新公共commit.能夠經過以下的命令進行合併

# Syntax: git merge <branch-name>
git merge testing


一旦合併發生了衝突,Git會標誌出來,開發人員須要手工的去解決這些衝突。解決衝突之後,就能夠將文件添加到索引中,而後提交更改


1.6.3 刪除分支


刪除分支的命令以下:

#Delete branch testing
git branch -d testing
# Check if branch has been deleted
git branch


1.6.4 推送(push)一個分支到遠端倉庫


默認的,Git只會推送匹配的分支的遠端倉庫。這意味在使用git push命令默認推送你的分支以前,須要手工的推送一次這個分支。

# Push testing branch to remote repository
git push origin testing

# Switch to the testing branch
git checkout testing

# Some changes
echo "News for you" > test01
git commit -a -m "new feature in branch"

# Push all including branch
git push

經過這種方式,你能夠肯定哪些分支對於其餘倉庫是可見的,而哪些只是本地的分支


1.7 解決合併衝突


若是兩個不一樣的開發人員對同一個文件進行了修改,那麼合併衝突就會發生。而Git沒有智能到自動解決合併兩個修改。


在這一節中,咱們會首先製造一個合併衝突,而後解決它,並應用到Git倉庫中。


下面會產生一個合併衝突


# Switch to the first directory
cd ~/repo01
# Make changes
touch mergeconflict.txt
echo "Change in the first repository" > mergeconflict.txt
# Stage and commit
git add . && git commit -a -m "Will create merge conflict 1"

# Switch to the second directory
cd ~/repo02
# Make changes
touch mergeconflict.txt
echo "Change in the second repository" > mergeconflict.txt
# Stage and commit
git add . && git commit -a -m "Will create merge conflict 2"
# Push to the master repository
git push

# Now try to push from the first directory
# Switch to the first directory
cd ~/repo01
# Try to push --> you will get an error message
git push
# Get the changes
git pull origin master


Git將衝突放在收到影響的文件中,文件內容以下:

<<<<<<< HEAD
Change in the first repository
=======
Change in the second repository
>>>>>>> b29196692f5ebfd10d8a9ca1911c8b08127c85f8


上面部分是你的本地倉庫,下面部分是遠端倉庫。如今編輯這個文件,而後commit更改。另外的,你可使用git mergetool命令

# Either edit the file manually or use 
git mergetool
# You will be prompted to select which merge tool you want to use
# For example on Ubuntu you can use the tool "meld"
# After  merging the changes manually, commit them
git commit -m "merged changes"


1.8 變基(Rebase)


1.8.1 在同一分支中應用Rebase Commit


經過rebase命令能夠合併多個commit爲一個。這樣用戶push更改到遠端倉庫的時候就能夠先修改commit歷史


接下來咱們將建立多個commit,而後再將它們rebase成一個commit


# Create a new file
touch rebase.txt

# Add it to git
git add . && git commit -m "rebase.txt added to index"

# Do some silly changes and commit
echo "content" >> rebase.txt
git add . && git commit -m "added content"
echo " more content" >> rebase.txt
git add . && git commit -m "added more content"
echo " more content" >> rebase.txt
git add . && git commit -m "added more content"
echo " more content" >> rebase.txt
git add . && git commit -m "added more content"
echo " more content" >> rebase.txt
git add . && git commit -m "added more content"
echo " more content" >> rebase.txt
git add . && git commit -m "added more content"

# Check the git log message
git log

咱們合併最後的七個commit。你能夠經過以下的命令交互的完成

git rebase -i HEAD~7

這個命令會打開編輯器讓你修改commit的信息或者 squash/ fixup最後一個信息.Squash會合並commit信息而fixup會忽略commit信息(待理解)

1.8.2 Rebasing多個分支

你也能夠對兩個分支進行rebase操做。以下所述,merge命令合併兩個分支的更改。rebase命令爲一個分支的更改生成一個補丁,而後應用這個補丁到另外一分支中

使用merge和rebase,最後的源代碼是同樣的,可是使用rebase產生的commit歷史更加的少,並且歷史記錄看上去更加的線性

# Create new branch 
git branch testing
# Checkout the branch
git checkout testing
# Make some changes
echo "This will be rebased to master" > test01
# Commit into testing branch
git commit -a -m "New feature in branch"
# Rebase the master
git rebase master


1.8.3 Rebase最佳實踐

在push更改到其餘的Git倉庫以前,咱們須要仔細檢查本地分支的commit歷史


在Git中,你可使用本地的commit。開發人員能夠利用這個功能方便的回滾本地的開發歷史。可是在push以前,須要觀察你的本地分支歷史,是否其中有些commit歷史對其餘用戶來講是無關的


若是全部的commit歷史都跟同一個功能有關,不少狀況下,你須要rebase這些commit歷史爲一個commit歷史。


交互性的rebase主要就是作重寫commit歷史的任務。這樣作是安全的,由於commit尚未被push到其它的倉庫。這意味着commit歷史只有在被push以前被修改。


若是你修改而後push了一個已經在目標倉庫中存在的commit歷史,這看起來就像是你實現了一些別人已經實現的功能


1.8.4 建立和應用補丁


一個補丁指的是一個包含對源代碼進行修改的文本文件。你能夠將這個文件發送給某人,而後他就能夠應用這個補丁到他的本地倉庫。


下面會建立一個分支,對這個分支所一些修改,而後建立一個補丁,並應用這個補丁到master分支


# Create a new branch
git branch mybranch
# Use this new branch
git checkout mybranch
# Make some changes
touch test05
# Change some content in an existing file
echo "New content for test01" >test01
# Commit this to the branch
git add .
git commit -a -m "First commit in the branch"

# Create a patch --> git format-patch master
git format-patch origin/master
# This created patch 0001-First-commit-in-the-branch.patch

# Switch to the master
git checkout master

# Apply the patch
git apply 0001-First-commit-in-the-branch.patch
# Do your normal commit in the master 
git add .
git commit -a -m "Applied patch"

# Delete the patch 
rm 0001-First-commit-in-the-branch.patch


1.9 定義同名命令


Git容許你設定你本身的Git命令。你能夠給你本身經常使用的命令起一個縮寫命令,或者合併幾條命令道一個命令上來。


下面的例子中,定義了git add-commit 命令,這個命令合併了git add . -A 和git commit -m 命令。定義這個命令後,就可使用git add-commit -m"message" 了.


git config --global alias.add-commit '!git add . -A && git commit'

可是很是不幸,截止寫這篇文章以前,定義同名命令在msysGit中尚未支持。同名命令不能以!開始。


1.10 放棄跟蹤文件


有時候,你不但願某些文件或者文件夾被包含在Git倉庫中。可是若是你把它們加到.gitignore文件中之後,Git會中止跟蹤這個文件。可是它不會將這個文件從倉庫中刪除。這致使了文件或者文件夾的最後一個版本仍是存在於倉庫中。爲了取消跟蹤這些文件或者文件夾,你可使用以下的命令


# Remove directory .metadata from git repo
git rm -r --cached .metadata
# Remove file test.txt from repo
git rm --cached test.txt

這樣作不會將這些文件從commit歷史中去掉。若是你想將這些文件從commit歷史中去掉,能夠參考git filter-branch命令


1.11 其餘有用的命令


下面列出了在平常工做中很是有用的Git命令


有用的Git命令


命令 描述
git blame filename 誰建立了或者是修改了這個文件
git checkout -b mybranch 以上上個commit信息爲起點,建立一條
master~1 新的分支


1.12 安裝Git服務


如上所述,咱們的操做不須要Git服務。我能夠只使用文件系統或者是Git倉庫的提供者,像Github或Bitbucket。可是,有時候,擁有一個本身的服務是比較方便的,在ubuntu下安裝一個服務相對來講是比較容易的


肯定你已經安裝了ssh

apt-get install ssh


若是你尚未安裝Git服務,安裝它

sudo apt-get install git-core


添加一個名爲git的用戶

sudo adduser git


而後使用git用戶進行登錄,建立一個空的倉庫

# Login to server
# to test use localhost
ssh git@IP_ADDRESS_OF_SERVER

# Create repository
git init --bare example.git


如今你就能夠向遠端的倉庫提交變動了

mkdir gitexample
cd gitexample
git init
touch README
git add README
git commit -m 'first commit'
git remote add origin git@IP_ADDRESS_OF_SERVER:example.git
git push origin master


1.13 在線的遠端倉庫


1.13.1 克隆遠端倉庫


Git支持遠端的操做。Git支持多種的傳輸類型,Git自帶的協議就叫作git。下面的的命令經過git協議從克隆一個倉庫

git clone git@github.com:vogella/gitbook.git


一樣的,你能夠經過http協議來克隆倉庫

# The following will clone via HTTP 
git clone http://vogella@github.com/vogella/gitbook.git


1.13.2 添加遠端倉庫

若是你克隆了一個遠端倉庫,那麼原先的倉庫就叫作origin

你能夠push修改到origin中,經過 git push origin 命令. 固然,push到一個遠端的倉庫須要對倉庫的寫權限

你能夠經過git remote add name gitrepo 命令添加多個倉庫。例如,你能夠經過http協議再次添加以前clone過來的倉庫:

// Add the https protocol 
git remote add githttp https://vogella@github.com/vogella/gitbook.git


1.13.3 經過http和代理服務器進行遠端操做

若是你的防火牆屏蔽了出http之外的全部協議,那麼使用http協議來獲取倉庫是很是好的方法。.

Git一樣支持經過代理服務器使用http協議。下面的Git命令會展現這一點。你能夠爲全部的程序設置代理服務器或者只是爲Git服務提供。

下面的例子用到了環境變量

# Linux
export http_proxy=http://proxy:8080
# On Windows
# Set http_proxy=http://proxy:8080 
git clone http://dev.eclipse.org/git/org.eclipse.jface/org.eclipse.jface.snippets.git
# Push back to the origin using http
git push origin


下面的例子只是用到了Git的配置

// Set proxy for git globally
 git config --global http.proxy http://proxy:8080
// To check the proxy settings
git config --get http.proxy
// Just in case you need to you can also revoke the proxy settings
git config --global --unset http.proxy


1.14 Git服務提供商

除了假設本身的服務,你也可使用Git服務提供商提供的服務。最流行的Git服務提供網站是GitHub和Bitbucket。它們都提供了有限制的免費服務


1.14.1 GitHub

能夠經過 https://github.com/ 訪問GitHub. GitHub上全部的公開倉庫都是免費的。若是你想在上面使用私有的倉庫,那麼就須要付費給GitHub


GitHub須要你建立ssh的公鑰私鑰。生成一份Ubuntu的公鑰私鑰能夠訪問 sshkey creation in Ubuntu ,Windows環境能夠訪問msysgit ssh key generation.


在GitHub上建立一個帳戶和一個倉庫之後。你會收到如何將你的項目上傳到GitHUb的指南,其中的命令大體以下:


Global setup:
 Set up git
  git config --global user.name "Your Name"
  git config --global user.email your.email@gmail.com
      
Next steps:
  mkdir gitbook 
  cd gitbook
  git init
  touch README
  git add README
  git commit -m 'first commit'
  git remote add origin git@github.com:vogella/gitbook.git
  git push -u origin master
      
Existing Git Repo?
  cd existing_git_repo
  git remote add origin git@github.com:vogella/gitbook.git
  git push -u origin master


1.14.2 Bitbucket


能夠經過 https://bitbucket.org/ 訪問Bitbucket. Bitbucket 提供了無限制了公共倉庫和只能有五我的訪問的私有倉庫。若是你須要超過五我的訪問私有倉庫,就須要付費給Bitbucket


1.15 Git的圖形接口


這個教程主要說明Git命令行的使用。完成了這個教程之後,你可能想要找到一個Git的圖形工具


Git提供了兩個圖形工具。 gitk可以展現倉庫的歷史信息、git gui 讓你能夠經過編輯器來完成Git操做


Eclipse EGit 項目提供了Git與Eclipse的集成,在最新的Eclipse版本中能夠找到


1.16 Kindle版本教程


這個教程提供了Kindle版本

Kindle Edition


1.17 問題與討論


在提出問題以前,請先查看 vogella FAQ. 若是你有任何的問題或者是從文章中找到錯誤,那麼可使用www.vogella.com Google Group. 我本身寫了一個簡短的列表 how to create good questions 可能會對你有用.


1.18 連接和文章


Git homepage

EGit - Teamprovider for Eclipse

Video with Linus Torwalds on Git

Progit book - Free Git book

Video casts about Git

http://code.google.com/p/msysgit/ Git on Windows

http://github.com/guides/git-cheat-sheet Git Cheat Sheets




Author: hic<lishuo.os.ds@gmail.com>

Date: 2012-08-26 日

HTML generated by org-mode 6.33x in emacs 23

相關文章
相關標籤/搜索