前言
最近本人將一些代碼放到了github上,順便總結了一下git的用法;經過了各種百度,最終形成了以下這篇文章。
個人感覺追求效率的話,只看最後一條git常用命令即可。
前面的似乎有用,又似乎沒用......
Git使用方法
- 簡介
Git 是一個開源的分佈式版本控制系統,用於敏捷高效地處理任何或小或大的項目。
Git 是 Linus Torvalds 爲了幫助管理 Linux 內核開發而開發的一個開放源碼的版本控制軟件。
Git 與常用的版本控制工具 CVS, Subversion 等不同,它採用了分佈式版本庫的方式,不必服務器端軟件支持。
- 安裝
Git 各平臺安裝包下載地址爲:http://git-scm.com/downloads
- Git工作流程
一般工作流程如下:
1.克隆 Git 資源作爲工作目錄。
2.在克隆的資源上添加或修改文件。
3.如果其他人修改了,你可以更新資源。
4.在提交前查看修改。
5.提交修改。
6.在修改完成後,如果發現錯誤,可以撤回提交併再次修改並提交。
下圖展示了 Git 的工作流程:
- Git 工作區、暫存區和版本庫
工作區:就是你在電腦裏能看到的目錄。
暫存區:英文叫stage, 或index。一般存放在 ".git目錄下" 下的index文件(.git/index)中,所以我們把暫存區有時也叫作索引(index)。
版本庫:工作區有一個隱藏目錄.git,這個不算工作區,而是Git的版本庫。
下面這個圖展示了工作區、版本庫中的暫存區和版本庫之間的關係:
圖中左側爲工作區,右側爲版本庫。在版本庫中標記爲 "index" 的區域是暫存區(stage, index),標記爲 "master" 的是 master 分支所代表的目錄樹。
圖中我們可以看出此時 "HEAD" 實際是指向 master 分支的一個"遊標"。所以圖示的命令中出現 HEAD 的地方可以用 master 來替換。
圖中的 objects 標識的區域爲 Git 的對象庫,實際位於 ".git/objects" 目錄下,裏面包含了創建的各種對象及內容。
當對工作區修改(或新增)的文件執行 "git add" 命令時,暫存區的目錄樹被更新,同時工作區修改(或新增)的文件內容被寫入到對象庫中的一個新的對象中,而該對象的ID被記錄在暫存區的文件索引中。
當執行提交操作(git commit)時,暫存區的目錄樹寫到版本庫(對象庫)中,master 分支會做相應的更新。即 master 指向的目錄樹就是提交時暫存區的目錄樹。
當執行 "git reset HEAD" 命令時,暫存區的目錄樹會被重寫,被 master 分支指向的目錄樹所替換,但是工作區不受影響。
當執行 "git rm --cached <file>" 命令時,會直接從暫存區刪除文件,工作區則不做出改變。
當執行 "git checkout ." 或者 "git checkout -- <file>" 命令時,會用暫存區全部或指定的文件替換工作區的文件。這個操作很危險,會清除工作區中未添加到暫存區的改動。
當執行 "git checkout HEAD ." 或者 "git checkout HEAD <file>" 命令時,會用 HEAD 指向的 master 分支中的全部或者部分文件替換暫存區和以及工作區中的文件。這個命令也是極具危險性的,因爲不但會清除工作區中未提交的改動,也會清除暫存區中未提交的改動。
- Git基本操作
1.git init
(1) 使用當前目錄做爲git倉庫:
git init
該命令執行完畢後會在當前目錄生成一個.git目錄。
(2) 使用指定目錄做爲git倉庫:
git init newrepo
該命令執行完畢後會在newrepo下生成.git目錄。
2.將文件納入版本控制:
$ git add *.c
$ git add README
$ git commit -m '初始化項目版本'
以上命令將當前目錄下以 .c 結尾及 README 文件提交到倉庫中。
3.git clone
(1)比如,要克隆代碼倉庫 Grit,可以用下面的命令:
$ git clone git://github.com/schacon/grit.git
執行該命令後,會在當前目錄下創建一個名爲grit的目錄,其中包含一個 .git 的目錄,用於保存下載下來的所有版本記錄。
(2)如果要自己定義要新建的項目目錄名稱,可以在上面的命令末尾指定新的名字:
$ git clone git://github.com/schacon/grit.git mygrit
Git 與常用的版本控制工具 CVS, Subversion 等不同,它採用了分佈式版本庫的方式,不必服務器端軟件支持。
4.git status
git status 以查看在你上次提交之後是否有修改。
使用 -s 參數,獲得簡短的結果輸出。如果沒加該參數會詳細輸出內容。
5.git diff
執行git diff來查看執行 git status 的結果的詳細信息。
git diff 命令顯示已寫入緩存與已修改但尚未寫入緩存的改動的區別。git diff 有兩個主要的應用場景。
尚未緩存的改動:git diff
查看已緩存的改動: git diff --cached
查看已緩存的與未緩存的所有改動:git diff HEAD
顯示摘要而非整個 diff:git diff --stat以查看在你上次提交之後是否有修改。
6.git commit
使用 git add 命令將想要快照的內容寫入緩存區, 而執行 git commit 將緩存區內容添加到倉庫中。
Git 爲你的每一個提交都記錄你的名字與電子郵箱地址,所以第一步需要配置用戶名和郵箱地址。
$ git config --global user.name 'runoob'
$ git config --global user.email [email protected]
接下來我們寫入緩存,並提交對 hello.php 的所有改動。在首個例子中,我們使用 -m 選項以在命令行中提供提交註釋。
$ git add hello.php
$ git commit -m '第一次版本提交'
如果你沒有設置 -m 選項,Git 會嘗試爲你打開一個編輯器以填寫提交信息。
如果你覺得 git add 提交緩存的流程太過繁瑣,Git 也允許你用 -a 選項跳過這一步。如下:
git commit -am '修改 hello.php 文件'
7.git reset HEAD
git reset HEAD 命令用於取消已緩存的內容。
$ git add .
$ git reset HEAD hello.php
現在你執行 git commit,就不會提交hello.php了。
8.git rm
如果只是簡單地從工作目錄中手工刪除文件,運行 git status 時就會在 Changes not staged for commit 的提示。
要從 Git 中移除某個文件,就必須要從已跟蹤文件清單中移除,然後提交。可以用以下命令完成此項工作
git rm <file>
如果刪除之前修改過並且已經放到暫存區域的話,則必須要用強制刪除選項 -f
git rm -f <file>
如果把文件從暫存區域移除,但仍然希望保留在當前工作目錄中,換句話說,僅是從跟蹤清單中刪除,使用 --cached 選項即可
git rm --cached <file>
可以遞歸刪除,即如果後面跟的是一個目錄做爲參數,則會遞歸刪除整個目錄中的所有子目錄和文件:
git rm –r *
進入某個目錄中,執行此語句,會刪除該目錄下的所有文件和子目錄。
9.git mv
git mv 命令用於移動或重命名一個文件、目錄、軟連接。
然後對其重名:
$ git mv README README.md
- Git分支管理
1.基本命令:
創建分支命令:
git branch (branchname)
切換分支命令:
git checkout (branchname)
當你切換分支的時候,Git 會用該分支的最後提交的快照替換你的工作目錄的內容, 所以多個分支不需要多個目錄。
合併分支命令:
git merge
你可以多次合併到統一分支, 也可以選擇在合併之後直接刪除被併入的分支。
2.列出分支:
列出分支基本命令:
git branch
沒有參數時,git branch 會列出你在本地的分支。
當你執行 git init 的時候,默認情況下 Git 就會爲你創建 master 分支。
用 git checkout (branch) 切換到我們要修改的分支。
也可以使用 git checkout -b (branchname) 命令來創建新分支並立即切換到該分支下,從而在該分支中操作。
3.刪除分支:
刪除分支命令:
git branch -d (branchname)
4.分支合併:
一旦某分支有了獨立內容,你終究會希望將它合併回到你的主分支。 你可以使用以下命令將任何分支合併到當前分支中去:
git merge
例如:
git merge newtest
將 newtest 分支合併到主分支去,test.txt 文件被刪除。
合併完後就可以刪除分支(也可以不刪):
$ git branch -d newtest
刪除後, 就只剩下 master 分支了。
5.合併衝突:
當分支中的文件發生了修改,並且主分支中同一個文件也發生了修改,此時將分支合併到主分支,就會發生衝突。
此時,需要手動修改這個文件:
$ vim runoob.php
$ cat runoob.php
<?php
echo 1;
echo 'runoob';
?>
之後,可以用 git add 要告訴 Git 文件衝突已經解決
$ git add runoob.php
- Git查看提交歷史
在使用 Git 提交了若干更新之後,又或者克隆了某個項目,想回顧下提交歷史,我們可以使用 git log 命令查看。
可以用 --oneline 選項來查看歷史記錄的簡潔的版本。
$ git log --oneline
還可以用 --graph 選項,查看歷史中什麼時候出現了分支、合併。
也可以用 --reverse 參數來逆向顯示所有日誌。
$ git log --reverse --oneline
如果只想查找指定用戶的提交日誌可以使用命令:git log --author。
$ git log --author=Linus --oneline -5
如果你要指定日期,可以執行幾個選項:--since 和 --before,但是你也可以用 --until 和 --after。
$ git log --oneline --before={3.weeks.ago} --after={2010-04-18} --no-merges
- Git標籤
如果你達到一個重要的階段,並希望永遠記住那個特別的提交快照,你可以使用 git tag 給它打上標籤。
比如說,我們想爲我們的 runoob 項目發佈一個"1.0"版本。 我們可以用 git tag -a v1.0 命令給最新一次提交打上(HEAD)"v1.0"的標籤。
-a 選項意爲"創建一個帶註解的標籤"。
$ git tag -a v1.0
當你執行 git tag -a 命令時,Git 會打開你的編輯器,讓你寫一句標籤註解,就像你給提交寫註解一樣。
現在,當我們執行 git log --decorate 時,就可以看到我們的標籤了。
如果我們忘了給某個提交打標籤,又將它發佈了,我們可以給它追加標籤。
例如,假設我們發佈了提交 85fc7e7(上面實例最後一行),但是那時候忘了給它打標籤。 我們現在也可以:
$ git tag -a v0.9 85fc7e7
如果我們要查看所有標籤可以使用以下命令:
$ git tag
指定標籤信息命令:
git tag -a <tagname> -m "runoob.com標籤"
PGP簽名標籤命令:
git tag -s <tagname> -m "runoob.com標籤"
- Git 遠程倉庫(Github)
Git 並不像 SVN 那樣有個中心服務器。
目前我們使用到的 Git 命令都是在本地執行,如果你想通過 Git 分享你的代碼或者與其他開發人員合作。你就需要將數據放到一臺其他開發人員能夠連接的服務器上。
1.添加遠程庫
要添加一個新的遠程倉庫,可以指定一個簡單的名字,以便將來引用,命令格式如下:
git remote add [shortname] [url]
本例以 Github 爲例作爲遠程倉庫,如果你沒有 Github 可以在官網 https://github.com/註冊。
由於你的本地 Git 倉庫和 GitHub 倉庫之間的傳輸是通過SSH加密的,所以我們需要配置驗證信息:
使用以下命令生成 SSH Key:
$ ssh-keygen -t rsa -C "[email protected]"
後面的 [email protected] 改爲你在 Github 上註冊的郵箱,之後會要求確認路徑和輸入密碼,我們這使用默認的一路回車就行。成功的話會在 ~/ 下生成 .ssh 文件夾,進去,打開 id_rsa.pub,複製裏面的 key。
回到 github 上,進入 Account => Settings(賬戶配置)。
左邊選擇 SSH and GPG keys,然後點擊 New SSH key 按鈕,title 設置標題,可以隨便填,粘貼在你電腦上生成的 key。
爲了驗證是否成功,輸入以下命令:
$ ssh -T [email protected]
Hi tianqixin! You've successfully authenticated, but GitHub does not provide shell access.
以下命令說明我們已成功連上 Github。
之後登錄後點擊" New repository " 。
之後在在Repository name 填入 runoob-git-test(遠程倉庫名) ,其他保持默認設置,點擊"Create repository"按鈕,就成功地創建了一個新的Git倉庫。
我們可以從這個倉庫克隆出新的倉庫,也可以把本地倉庫的內容推送到GitHub倉庫。
現在,我們根據 GitHub 的提示,在本地的倉庫下運行命令:
$ mkdir runoob-git-test # 創建測試目錄
$ cd runoob-git-test/ # 進入測試目錄
$ echo "# 菜鳥教程 Git 測試" >> README.md # 創建 README.md 文件並寫入內容
$ ls # 查看目錄下的文件
README
$ git init # 初始化
$ git add README.md # 添加文件
$ git commit -m "添加 README.md 文件" # 提交併備註信息
[master (root-commit) 0205aab] 添加 README.md 文件
1 file changed, 1 insertion(+)
create mode 100644 README.md
# 提交到 Github
$ git remote add origin [email protected]:tianqixin/runoob-git-test.git
$ git push -u origin master
以上命令請根據你在Github成功創建新倉庫的地方複製,而不是根據我提供的命令,因爲我們的Github用戶名不一樣,倉庫名也不一樣。
接下來我們返回 Github 創建的倉庫,就可以看到文件已上傳到 Github上。
2.查看當前的遠程庫
要查看當前配置有哪些遠程倉庫,可以用命令:
git remote
執行時加上 -v 參數,你還可以看到每個別名的實際鏈接地址。
$ git remote -v
3.提取遠程倉庫
Git 有兩個命令用來提取遠程倉庫的更新。
(1)從遠程倉庫下載新分支與數據:
git fetch
該命令執行完後需要執行git merge 遠程合併到你所在的分支。
(2)從遠端倉庫提取數據並嘗試合併到當前分支:
git merge
該命令就是在執行 git fetch 之後緊接着執行 git merge 遠程分支到你所在的任意分支。
例:
$ git fetch origin
$ git merge origin/master
4.推送到遠程倉庫
推送你的新分支與數據到某個遠端倉庫命令:
git push [alias] [branch]
以上命令將你的 [branch] 分支推送成爲 [alias] 遠程倉庫上的 [branch] 分支,實例如下。
$ touch runoob-test.txt # 添加文件
$ git add runoob-test.txt
$ git commit -m "添加到遠程"
master 69e702d] 添加到遠程
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 runoob-test.txt
$ git push origin master # 推送到 Github
5.刪除遠程倉庫
刪除遠程倉庫你可以使用命令:
git remote rm [別名]
實例
# 添加倉庫 origin2
$ git remote add origin2 [email protected]:tianqixin/runoob-git-test.git
# 刪除倉庫 origin2
$ git remote rm origin2
$ git remote -v
origin [email protected]:tianqixin/runoob-git-test.git (fetch)
origin [email protected]:tianqixin/runoob-git-test.git (push)
- 命令行中github的用法
1.使用命令
ssh-keygen -t rsa -C "[email protected]"
參數爲github郵箱;輸入文件保存地址,輸入github密碼;之後生成pub文件
2.回到 github 上,進入 Account => Settings(賬戶配置),選擇 SSH and GPG keys,然後點擊 New SSH key 按鈕,title 設置標題,可以隨便填,粘貼在你電腦上生成的 pub文件的內容。
3.輸入以下命令測試:ssh -T [email protected];如果失敗,則搜索.ssh文件夾(C:\Users\Admin\.ssh),將第一步生成的兩個文件粘貼到此處,並重命名爲id_rsa與id_rsa.pub
4.在github中點擊New respository,之後在Repository name 填入 runoob-git-test(遠程倉庫名) ,其他保持默認設置,點擊"Create repository"按鈕,就成功地創建了一個新的Git倉庫。
5.按照提示信息創建一個測試文件並上傳到git倉庫:
echo "# 菜鳥教程 Git 測試" >> README.md
git init
git add README.md
git commit -m "123"
git remote add origin https://github.com/BlackHoleSeventh/gitest.git
git push -u origin master
之後需要輸入用戶名與密碼,之後就上傳成功了。
6.將一個已有的項目上傳到github:
(1) cd到已有項目的目錄中,使用git init;命令初始化
(2) 使用git add * ;將所有項目添加到git
(3) 使用git commit -m “任意信息”將添加後的文件提交
(4) 使用git remote add myStore https://github.com/UserName/storeName.git添加一個遠程倉庫地址;其中myStore是自己起的倉庫名,對應後面的地址;使用git remote -v即可查看自己有哪些倉庫地址。
(5) 使用git push -u myStore master將代碼推送到遠程倉庫的master分支中,其中myStore是自己起的倉庫名,master是分支名。(可以任意起,如果遠程倉庫沒有這個分支,則會創建一個)
7.將一個github項目更新到本地:
(1) cd到目標目錄中,使用git fetch myStore命令拉到本地(沒有參數,從遠程master拉到了本地master目錄中);其中myStore是自己起的倉庫名(對應url用)。
(2) 使用git merge myStore/master命令將內容同步。其中myStore是自己起的倉庫名,master是同步到本地master分支。
8.將一個github項目下載到本地空文件夾:
(1) cd到目標空文件夾中,使用git clone https://github.com/UserName/storeName.git name命令,其中url爲github倉庫的網址,name爲自己起的文件夾名,也可以不加,則會使用storeName爲文件夾名。clone操作是一個從無到有的克隆操作,不需要git init初始化。
(2) 也可以使用git pull,相當於從遠程倉庫獲取最新版本,然後再與本地分支merge(合併)。
舉例:將遠程主機origin的master分支拉取過來,與本地的branchtest分支合併。
$ git pull origin master:branchtest
(3) 以上的git pull操作也可以用git fetch來表示:
$ git fetch origin master:brantest
$ git merge brantest
將遠程master分支下載到本地brantest分支;
將brantest分支合併入主分支master。
使用fetch可以先查看代碼不同,再決定是否合併。
git fetch更新本地倉庫的兩種用法:
# 方法一
$ git fetch origin master #從遠程的origin倉庫的master分支下載代碼到本地的origin master
$ git log -p master.. origin/master #比較本地的倉庫和遠程參考的區別
$ git merge origin/master #把遠程下載下來的代碼合併到本地倉庫,遠程的和本地的合併
# 方法二
$ git fetch origin master:temp #從遠程的origin倉庫的master分支下載到本地並新建一個分支temp
$ git diff temp #比較master分支和temp分支的不同
$ git merge temp #合併temp分支到master分支
$ git branch -d temp #刪除temp
9.Git回滾:
(1) 使用git log --pretty=oneline查看歷史版本
(2) 使用git reset --hard 9e4a2468e8ecb8d763b7e53549bd982c3370d00d回退到指定版本
10.git上傳大文件:
(1) 在項目目錄下,使用git lfs install命令
(2) 使用命令:git lfs track “* .gif” --這裏的 “ *.gif "就是你要上傳的大文件的路徑
(3) 使用命令:git add .gitattributes
(4) 先提交:git commit -m "123";
(5) 先上傳:git push -u orgin master
(6) 之後再上傳大文件。注意,一定要先上傳.gitattributes文件纔可以!
11.git撤銷add命令:
git reset HEAD //可以全部恢復未提交狀態
git reset --hard HEAD //把全部更改的文件都恢復(小心使用,不然辛辛苦苦寫的全沒了)
- Idea中git的用法
1.cd到指定目錄,使用命令
git init
git add *
git commit -m “msg”
git remote add orgin https://github.com/UserName/UserStore.git
git push -u orgin master
將代碼同步到遠程倉庫
2.或者使用
git clone git://github.com/UserName/UserStore.git
將代碼下載到本地
3.使用idea打開項目,會出現提示是否要用git管理項目,選“yes”
4.或者,上方vcs菜單中有checkout from version control子菜單,其中可以設置git地址。
5.在右下角“Git:master”處,點擊選擇“New Branch”可以添加新分支
6.在右下角選擇“check out”選擇目標分支
7.上方有update按鈕與commit按鈕,commit按鈕可以選擇commit and push;之後會要求輸入用戶名密碼,即可push到遠程倉庫。
8.下方“version control”中可以查看正在修改的文件,可以選擇commit或revert。
9.上方vcs菜單中有git子菜單,可以選擇revert、clone、fetch、pull、push等操作。
10.分支代碼更新後,可以回到主分支,選擇另一個分支的merge,即可將分支代碼同步到主分支;主分支代碼更新後,也可以先進入從分支,選擇主分支的merge,即可將代碼同步到當前分支。
11.當一個分支的代碼push後,可以進入其它分支merge此分支的代碼,如果此時merge其餘分支的代碼,則不會有反應,因爲git只保存一個提交對象。
12.當兩個以上從分支push後,主分支想merge其中一個分支,則會發生衝突,需要選擇接受哪一個分支。
- TortoiseGit的用法
1.安裝
2.安裝好後,右鍵可以發現TortoiseGit的相關菜單
3.選擇git clone從倉庫下載代碼,或者選擇git create repository here...創建.git文件夾
4.可以使用commit、push、revert操作代碼
5.可以使用create branch創建分支,使用Switch/Checkout切換分支。
6.先進入目標分支,然後選擇merge,再選擇另一個分支,就可以將代碼合併到目標分支上。
7.刪除分支:點擊“Switch/Checkout”打開對話框,點擊Switch to區域中Branch條目後面的更多按鈕,打開分支列表對話框,右鍵點擊要刪除的分支,選擇delete branch進行刪除。
- Git衝突與解決方法
1、git衝突的場景
情景一:多個分支代碼合併到一個分支時;
情景二:多個分支向同一個遠端分支推送代碼時;
實際上,push操作即是將本地代碼merge到遠端庫分支上。
關於push和pull其實就分別是用本地分支合併到遠程分支 和 將遠程分支合併到本地分支
所以這兩個過程中也可能存在衝突。
git的合併中產生衝突的具體情況:
(1)兩個分支中修改了同一個文件(不管什麼地方)
(2)兩個分支中修改了同一個文件的名稱
兩個分支中分別修改了不同文件中的部分,不會產生衝突,可以直接將兩部分合並。
2、衝突解決方法
情景一:在當前分支上,直接修改衝突代碼--->add--->commit。
情景二:在本地當前分支上,修改衝突代碼--->add--->commit--->push
注:借用vim或者IDE或者直接找到衝突文件,修改。
- 個人總結:Git常用命令
--------------------------------------------
//git上傳本地項目以及上傳大文件
git init
git remote add orgin https://github.com/UserName/UserStore.git
git lfs install
git lfs track "*.*"
git add .gitattributes
git commit -m "LFS上傳大文件"
git push -u orgin master
git add *
git commit -m "上傳已存在項目"
git push -u orgin master
--------------------------------------------
//git從倉庫下載項目(還有clone與pull,不過只用fetch也可以)
git init
git remote add orgin https://github.com/UserName/UserStore.git
git fetch orgin
git merge orgin/master
--------------------------------------------
//git查看提交歷史
git log --pretty=oneline
--------------------------------------------
//git revert,生成一個新的提交來撤銷某次提交,此次提交之前的commit都會被保留
git revert HEAD #撤銷倒數第一次提交
git revert HEAD^ #撤銷倒數第二次提交
git revert HEAD~2 #撤銷倒數第三次提交
git revert c011eb3c20ba6fb38cc94fe5a8dda366a3990c61
--------------------------------------------
//git reset,回到某次提交,提交及之前的commit都會被保留,但是此次之後的修改都會被退回到暫存區,用法與revert類似
//git取消add操作
git reset HEAD
//只回退某個指定文件到指定版本
git reset a4e215234aa4927c85693dca7b68e9976948a35e MainActivity.java
--------------------------------------------