Tortoise Git安裝包下載地址
https://tortoisegit.org/download/
git安裝時祕鑰生成步驟
1. git config --global user.name xxx 2. git config --global user.email xxx@xxx 3. ssh-keygen -C xxx@xxx -t rsa
//第3步分為下面3個小步驟 (1)公鑰儲存地址 按回車選擇預設 (2)私鑰密碼-為了後續使用方便 設定為空 (3)生成公鑰和私鑰
identification has been saved in /c/Users/xxx/.ssh/id_rsa.
public key has been saved in /c/Users/xxx/.ssh/id_rsa.pub.
// git公鑰------/c/Users/xxx/.ssh/id_rsa.pub.檔案中的內容
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC/pYFUKMZUPNJtjOdSQl74GH4JxAQ8F+EqaMoR9Yw+5VNW81eWrrbbSsjpEDPaZIbb0Sc89oJ4Uzi2lpHjhTujMmdzf2TrfOaGRa2+M5Ey4Z1MXuT4RVawrZ/PtK7tTI+eMKc
/NZqhcp9e+NYIVzbwUMqvAnx+OTgDF3RYmYWDcbvTX0AybOBd/NwV1BtR5PkPRHlGQN0Oi5wHmvXmP9WIQ9dAoi+w63mhL+c8a8Qu+PBZBiknzJRB1p9dtIOEPdq5ltGAqluEZ0FTEzet1qH0pAUaOxxEsZAhGpa9453rQJ433
Emg7hy30KomOQvFp64T6QlTGFKIg9EMm9t8Ny2r xxx@xxx
git推薦使用SSH協議的原因
使用SSH協議可以避免每次push
輸入密碼。前提是在賬戶裡配置好SSH祕鑰。 git@github.com開頭的就是SSH協議。 使用Https協議則會導致每次都會輸入使用者名稱和密碼。
git bash命令視窗和字型的大小設定
滑鼠點選git bash介面的標題欄,滑鼠右鍵選擇
// 視窗尺寸設定
options --> windows -->修改行數(高度)+列數(寬度)
// 視窗字型設定
options --> text -->設定字型大小
擴充套件
// 瞭解一下win7的命令視窗設定
http://article.pchome.net/content-1245289-all.html
建立本地庫
// 從零開始建立
1.git init 建立一個空的Git庫。在當前目錄中產生一個.git 的子目錄。以後,所有的檔案變化資訊都會儲存到這個目錄下 2.git init --bare 建立備份倉庫(在伺服器或者工程目錄以外路徑都可以建立的備份倉庫)
// 克隆已有倉庫建立
git clone /path/to/repository // 本地庫
git clone git/ssh/http[s]/ftp[s]/file/rsync:username@ip/path/to/repository // 遠端伺服器
git clone的本質就是把“Git目錄”裡面的內容拷貝過來,一般的“Git目錄”裡有成千上萬的各種物件(提交物件,樹物件,二進位制物件, tag物件......),如果逐一複製的話,其效率就可想而知。
如果通過git、ssh協議傳輸,伺服器端會在傳輸前把需要傳輸的各種物件先打好包再進行傳輸;而http(s)協議則會反覆請求要傳輸的不同物件。如果倉庫裡面的提交不多的話,前者和後者的效率相差不多;但是若倉庫裡有很多提交的話,git、ssh協議進行傳輸則會更有效率。不過現在Git對http(s)協議傳輸Git倉庫做了一定的優化,http(s)傳輸現在也能達到ssh協議的效率
.git目錄的組成
COMMIT_EDITMSG # 儲存著上一次提交時的註釋資訊 config # 專案的配置資訊 description # 專案的描述資訊 HEAD # 專案當前在哪個分支的資訊
index # 索引檔案,git add之後要新增的內容暫存在這裡 hooks/ # 預設的“hooks” 指令碼檔案 info/ # 裡面有一個exclude檔案,指定本專案要忽略的檔案 #,看一下這裡 logs/ # 各個refs的歷史資訊 objects/ # 這個目錄非常重要,裡面儲存都是Git的資料物件 # 包括:提交(commits), 樹物件(trees),二進位制物件 #(blobs),標籤物件(tags)。
# 在objects目錄下,SHA串的前兩個字元作為目錄名,後面的38個字元作為檔名
refs/ # 標識著你的每個分支指向哪個提交(commit)。
// 檢視提交檔案的內容,2d832d是SHA(安全hash演算法)簽名值
$ git cat-file -p 2d832d
// 詳細請參考 本地倉庫的建立和構成
http://www.infoq.com/cn/news/2011/02/git-adventures-local-repository
配置選項
git config, -- 僅對當前專案
--global -- 對當前登入者
--system -- 對所有登入這臺電腦的人
git config -e --[local|global|system]
工作流
本地和遠端工作流
你的原生程式碼 由 git 維護的三棵“樹”組成。第一個是你的 工作目錄
,它持有實際檔案;第二個是 快取區(Index/stage)
,它像個快取區域,臨時儲存你的改動;最後是本地倉庫( HEAD)
,指向你最近一次提交後的結果。
git clone 用於建立本地倉庫 // origin 是git clone預設使用的遠端主機名
通過git clone獲取遠端git庫後,.git/config中的開發者資訊不會被一起clone過來。仍然需要為本地庫的.git/config檔案新增開發者資訊。此外,開發者還需要自己新增 . gitignore檔案。
通過git clone獲取的遠端git庫,只包含了遠端git庫的當前工作分支。如果想獲取其它分支資訊,需要使用 “git branch –r” 來檢視, 如果需要將遠端的其它分支程式碼也獲取過來,可以使用命令 “ git checkout -b 本地分支名 遠端分支名”,
其中,遠端分支名為 “git branch –r” 所列出的分支名, 一般是諸如“origin/分支名”的樣子。如果本地分支名已經存在, 則不需要“-b”引數。
git fetch
從遠端獲取最新版本到本地,不會自動merge,比git pull更安全些。
如果先使用 git fetch ,再使用git checkout nov/eclair_rocket,則是先從伺服器上獲取最新的更新資訊,然後從伺服器上下載最新的程式碼。
git pull
從伺服器的倉庫中獲取程式碼,和原生程式碼合併。等同於: Git fetch + Git merge
這條命令將從遠端git庫的遠端分支名獲取到本地git庫的一個本地分支中。其中,如果不寫本地分支名,則預設pull到本地當前分支。 如果你的本地分支已經有內容,則git pull會合並這些檔案,如果有衝突會報警。
git pull
和git push
是針對所有分支進行的操作。也就是說即使我切換到一個次分支alpha
, 如果這個分支和遠端的分支已關聯了的話,那麼執行git pull
會把master
分支和alpha
分支都更新到遠端。
本地關聯遠端分支
git push --set-upstream origin 遠端分支名
推送改動
你的改動現在已經在本地倉庫的 HEAD 中了。執行如下命令以將這些改動提交到遠端倉庫:
git push origin master
git push不會自動合併檔案。因此,如果git push時,發生了衝突,就會被後push的檔案內容強行覆蓋,而且沒有什麼提示。 這在合作開發時是很危險的事情。
可以把master換成你想要推送的任何分支。
如果你還沒有克隆現有倉庫,並欲將你的倉庫連線到某個遠端伺服器,你可以使用如下命令新增:
git remote add origin <server>
如此你就能夠將你的改動推送到所新增的伺服器上去了
新增與提交
你可以計劃改動(把它們新增到快取區),使用如下命令:
git add dir1 # 新增dir1這個目錄,目錄下的所有檔案都被加入 git add f1 f2 # 新增f1,f2檔案 git add -u #將本地的(修改和刪除,沒有新增)檔案新增到暫存區 git add . #把前目錄下的所有檔案全部新增到暫存區(不包括.gitignore中要忽略的檔案)都新增到git緩衝區以待提交
git add * #將本地所有有改動的檔案(包括.gitignore中要忽略的檔案)都新增到git緩衝區以待提交 git add -A 等於 git add . + git add -u git rm --cache a.c #刪除已提交到本地倉庫的檔案
這是 git 基本工作流程的第一步;使用如下命令以實際提交改動:
git commit -m "程式碼提交資訊" git commit -a -m "程式碼提交資訊" # git commit -a是把unstaged的檔案變成staged(這裡不包括新建(untracked)的檔案),然後commit git commit --amend # 修改提交的commit(沒有push) git commit --amend -m "comment" # 修改commit註解
現在,你的改動已經提交到了 HEAD,但是還沒到你的遠端倉庫。
git刪除
git rm與git rm --cached
當我們需要刪除暫存區
或分支
上的檔案, 同時工作區也不需要這個檔案了, 可以使用
1 git rm file_path 2 git commit -m 'delete somefile' 3 git push
當我們需要刪除暫存區
或分支
上的檔案, 但本地又需要使用, 只是不希望這個檔案被版本控制, 可以使用
git rm --cached file_path git commit -m 'delete remote somefile' git push
分支
新建一個跟蹤遠端分支的本地分支
git checkout -b [branch] origin/[branch]
分支是用來將特性開發絕緣開來的。在你建立倉庫的時候,master 是“預設的”。在其他分支上進行開發,完成後再將它們合併到主分支上。
git checkout -b feature_x建立一個叫做“feature_x”的分支,並切換過去:
切換回主分支:
git checkout master
再把新建的分支刪掉:
git branch -d feature_x
除非你將分支推送到遠端倉庫,不然該分支就是 不為他人所見的:
git push origin <branch>
重新命名本地分支
git branch -m branch-old-name branch-new-name
刪除遠端分支
git push origin --delete test_branch
分支切換
git 切換分支時,如果當前分支開發到一半,沒有提交,會被帶到另一分支
使用git stash命令暫存
使用git stash pop 恢復
使用git stash list 檢視暫存內容
使用git stash clear 刪除暫存內容
更新
要更新你的本地倉庫至最新改動,執行:
git pull origin <remote-branch> <local-branch>
git fetch origin <remote-branch>
git pull --ff 出現編輯介面的退出方法
先按esc,然後shift+:,wq就是儲存退出
標籤
在軟體釋出時建立標籤,是被推薦的。這是個舊有概念,在 SVN 中也有。可以執行如下命令以建立一個叫做 1.0.0 的標籤:
git tag 1.0.0 1b2e1d63ff
1b2e1d63ff 是你想要標記的提交 ID 的前 10 位字元。使用如下命令獲取提交 ID:
git log
你也可以用該提交 ID 的少一些的前幾位,只要它是唯一的。
// 給tag新增註釋 git tag -v1.4 -m 'my version 1.4'
// 顯示tag版本記錄
git show tag-name
// 一次性推送所有tag到遠端伺服器
git push origin --tags
// 取出打過tag的某個版本
git checkout -b branch_name tag_name
// 刪除tag時需注意,如果向遠端伺服器提交了tag,則刪除tag時,不僅要刪除本地的tag,還要刪除遠端的tag // 刪除本地的tag命令是 git tag -d tag-name // 刪除遠端tag的命令是 git push origin --delete tag-name
替換本地改動
假如你做錯事(自然,這是不可能的),你可以使用如下命令替換掉本地改動:
git checkout -- <filename>
此命令會使用 HEAD 中的最新內容替換掉你的工作目錄中的檔案。已新增到快取區的改動,以及新檔案,都不受影響。
假如你想要丟棄你所有的本地改動與提交,可以到伺服器上獲取最新的版本並將你本地主分支指向到它:
git fetch origin master
git reset origin/master --hard
git 忽略檔案的設定方式
可參考以下兩個網址
git ignore檔案的三種設定方式[http://www.jianshu.com/p/267cd94f1d49 ]
git ignore檔案設定的具體語法[http://www.cnblogs.com/pylemon/archive/2012/07/16/2593112.html#3226325]
重點說一下踩過的坑:
.gitignore 檔案可以忽略自己。忽略的檔案,只針對未跟蹤檔案有效,對已加入版本庫的檔案無效。
git check-ignore 可用來檢查所寫的忽略檔案語法是否正確
忽略檔案的原則是:
1.忽略作業系統自動生成的檔案,比如縮圖等;
2.忽略編譯生成的中間檔案、可執行檔案等,也就是如果一個檔案是通過另一個檔案自動生成的,那自動生成的檔案就沒必要放進版本庫,比如Java編譯產生的.class
檔案;
3.忽略你自己的帶有敏感資訊的配置檔案,比如存放口令的配置檔案。
不需要從頭寫.gitignore
檔案,GitHub已經為我們準備了各種配置檔案,只需要組合一下就可以使用了,比如分別輸入Tags和SublimeText,在下面的網址中查詢忽略規則 https://www.gitignore.io/
git 分支合併
假設此時,你突然接到一個電話說有個很嚴重的問題需要緊急修補,那麼可以按照下面的方式處理:
- 返回到原先已經發布到生產伺服器上的分支。
- 為這次緊急修補建立一個新分支,並在其中修復問題。
- 通過測試後,回到生產伺服器所在的分支,將修補分支合併進來,然後再推送到生產伺服器上。
- 切換到之前實現新需求的分支,繼續工作。
$ git checkout -b iss53 // 在master分支上新建一個iss53分支
相當於執行下面這兩條命令:
$ git branch iss53
$ git checkout iss53
// 將hotfix分支合併到master $ git checkout master $ git merge hotfix --no-ff
合併分支時,如果可能,Git會用Fast forward
模式,但這種模式下,刪除分支後,會丟掉分支資訊。如果要強制禁用Fast forward
模式,Git就會在merge時生成一個新的commit,這樣,從分支歷史上就可以看出分支資訊。
git merge 分支名 --no-ff -m" 本次合併新增的註釋資訊"
合併時發生衝突的提示資訊
$ git merge iss53 Auto-merging index.html CONFLICT (content): Merge conflict in index.html Automatic merge failed; fix conflicts and then commit the result.
合併狀態的檢視
$ git status On branch master You have unmerged paths. (fix conflicts and run "git commit") Unmerged paths: (use "git add <file>..." to mark resolution) both modified: index.html no changes added to commit (use "git add" and/or "git commit -a")
任何包含未解決衝突的檔案都會以未合併(unmerged)的狀態列出。Git 會在有衝突的檔案里加入標準的衝突解決標記,可以通過它們來手工定位並解決這些衝突。可以看到此檔案包含類似下面這樣的部分:
<<<<<<< HEAD <div id="footer">contact : email.support@github.com</div> ======= <div id="footer"> please contact us at support@github.com </div> >>>>>>> iss53
可以看到 =======
隔開的上半部分,是 HEAD
(即 master
分支,在執行 merge
命令時所切換到的分支)中的內容,下半部分是在 iss53
分支中的內容。解決衝突的辦法無非是二者選其一或者由你親自整合到一起。比如你可以通過把這段內容替換為下面這樣來解決:
這個解決方案各採納了兩個分支中的一部分內容,而且我還刪除了 <<<<<<<
,=======
和 >>>>>>>
這些行。在解決了所有檔案裡的所有衝突後,執行 git add
將把它們標記為已解決狀態(譯註:實際上就是來一次快照儲存到暫存區域。)。因為一旦暫存,就表示衝突已經解決。
git branch -d studyGit // 對studyGit分支進行合併後,才能刪除得了studyGit分支 git branch -D studyGit // 強制刪除studyGit分支
再執行一次 git status
來確認所有衝突都已解決:
$ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: index.html
如果覺得滿意了,並且確認所有衝突都已解決,也就是進入了暫存區,就可以用 git commit
來完成這次合併提交。提交的記錄差不多是這樣:
git rebase 合併出錯
git rebase --abort 終止合併
git rebase --continue 繼續合併
Git - 分支的新建與合併可參考下文
git merge和git rebase 合併分支的差異
http://gitbook.liuhui998.com/4_2.html
git rebase生成的歷史記錄線比較好看
開發過程中,若你在開發的branch功能比較多, commit的量也比較多時,建議使用rebase將你現在的branch整理過再合併回主幹,這樣會產生較漂亮的線
git版本庫回滾
1、git checkout the_branch 2、git pull 3、git branch the_branch_backup //備份一下這個分支當前的情況 4、git reset --hard the_commit_id //把the_branch本地回滾到the_commit_id 5、git push origin :the_branch //刪除遠端 the_branch 6、git push origin the_branch //用回滾後的本地分支重新建立遠端分支 7、git push origin :the_branch_backup //如果前面都成功了,刪除這個備份分支
--soft 回退commit --mixed 回退commit和stage --hard 回退commit stage workspace //本地倉庫回退到某個版本 git reset version_hash --hard // 推送至遠端倉庫,使遠端倉庫回退到某個版本 git push 遠端主機名 遠端目錄 -f
Git的版本回退速度非常快,因為Git在內部有個指向當前版本的HEAD
指標,當你回退版本的時候,Git僅僅是把HEAD從指向append GPL
版本號沒必要寫全,前幾位就可以了,Git會自動去找。當然也不能只寫前一兩位,因為Git可能會找到多個版本號,就無法確定是哪一個了。
git reset --hard 3628164
git log退出
在英文輸入狀態下,按Q就退出了
git revert和git reset的區別
http://blog.csdn.net/caz28/article/details/43602879
git revert 和 git reset 只有在回退最近的一次提交時,才是等效的
(1)git revert會使提交記錄增多,git reset會使提交記錄減少
(2)git revert只是撤銷指定版本的提交,git reset是回捲,會撤銷指定版本之後的所有提交
git reset HEAD~3
git revert HEAD~3
(3) git reset只能針對本地操作,不能對遠端伺服器執行同樣的操作。
git revert和get reset的後悔藥
revert後如果不想撤銷了,看一下log,reset回去就可以了。
reset後後悔了怎麼辦,沒有log了!沒關係,下面命令可以查到更多commit ID:
git reflog
再輸入:
git reset <commit ID>
這個commit ID是上次reset前的ID,就可以回退會reset以前狀態了。
在Git中,總是有後悔藥可以吃的
git reflog 記錄你操作的每一條指令
-
HEAD
指向的版本就是當前版本,因此,Git允許我們在版本的歷史之間穿梭,使用命令git reset --hard commit_id
。 -
穿梭前,用
git log
可以檢視提交歷史,以便確定要回退到哪個版本。 -
要重返未來,用
git reflog
檢視命令歷史,以便確定要回到未來的哪個版本。
// 可參考這篇文章 版本回退
// git revert
http://samael65535.github.io/git/2013/01/18/git/
有用的貼士
內建的圖形化 git:gitk
彩色的 git 輸出:git config color.ui true
顯示歷史記錄時,只顯示一行註釋資訊:git config format.pretty oneline
如果嫌輸出資訊太多,看得眼花繚亂的,可以試試加上--pretty=oneline
引數:
git log --pretty=oneline --abbrev-commit
你看到的一大串類似3628164...882e1e0
的是commit id
(版本號),和SVN不一樣,Git的commit id
不是1,2,3……遞增的數字,而是一個SHA1計算出來的一個非常大的數字,用十六進位制表示,而且你看到的commit id
和我的肯定不一樣,以你自己的為準。為什麼commit id
需要用這麼一大串數字表示呢?因為Git是分散式的版本控制系統,後面我們還要研究多人在同一個版本庫裡工作,如果大家都用1,2,3……作為版本號,那肯定就衝突了。
在Git中,用HEAD
表示當前版本,也就是最新的提交3628164...882e1e0
(注意我的提交ID和你的肯定不一樣),上一個版本就是HEAD^
,上上一個版本就是HEAD^^
,當然往上100個版本寫100個^
比較容易數不過來,所以寫成HEAD~100
。
跟蹤分支的概念
使用心得:
1.要看一下每條git命令的回顯,看看是不是你要執行的操作, 有沒有遺漏或報錯或者執行終止的情況
2.對於異常操作,一定要保留現場,查明原因,這樣記憶更深刻。
想進一步瞭解git指令的話,可閱讀下面幾篇文章
git 入門級指令
https://github.com/guodongxiaren/LinuxTool/blob/master/git.md
git常用命令解說
http://zensheno.blog.51cto.com/2712776/490748
git常用命令總結
http://blog.csdn.net/a396901990/article/details/43428905
git簡明教程
http://shahdza.blog.51cto.com/2410787/1616345
比較系統的git教程