git 學習筆記

最近看了廖雪峯老師的git教程,通俗易懂,操做性很強,是很好的入門教程,javascript

網站連接:https://www.liaoxuefeng.com/,現記錄下學習筆記java

一、安裝步驟

在Windows上安裝Git

在Windows上使用Git,能夠從Git官網直接(https://git-scm.com/downloads),而後按默認選項安裝便可。安裝完成後,在開始菜單裏找到「Git」->「Git Bash」,蹦出一個相似命令行窗口的東西,就說明Git安裝成功!git

git-bash默認不能複製黏貼須要設置github

使用的時候ctrl+c ,在git-bash中右鍵就能夠複製安全

注意git-bash使用的命令與用cmd打開控制檯命令有區別,切換e盤git-bash使用的命令是cd e:     cmd打開控制檯使用的命令是e:bash

安裝完成後,還須要最後一步設置,在命令行輸入:app

$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"

二、建立版本庫 

(1)在合適的地方新建一個文件夾learngit,cd 進入這個文件夾,pwd後會顯示這個文件夾的目錄ssh

(2)經過命令$ git init把這個目錄變成Git能夠管理的倉庫,這時learngit文件夾中多了一個.git目錄,這個目錄是Git來跟蹤管理版本庫的,不要改動,若是你沒有看到.git目錄,那是由於這個目錄默認是隱藏的,用ls -ah命令就能夠看見。編輯器

(3)用notepade++或者其它編輯器(不要用記事本) 新建一個文件readme.txt,並輸入內容,放到learngit文件夾裏學習

(4)用命令$ git add readme.txt告訴Git,把文件添加到倉庫

(5)用命令$ git commit -m "wrote a readme file"告訴Git,把文件提交到倉庫

爲何Git添加文件須要addcommit一共兩步呢?由於commit能夠一次提交不少文件,因此你能夠屢次add不一樣的文件,好比:

$ git add file1.txt
$ git add file2.txt file3.txt
$ git commit -m "add 3 files."

三、時光機穿梭 

咱們已經成功地添加並提交了一個readme.txt文件,如今,是時候繼續工做了,因而,咱們繼續修改readme.txt文件,修改後運行$ git status命令看看結果:

雖然Git告訴咱們readme.txt被修改了,但若是能看看具體修改了什麼內容,天然是很好的,經過命令查看修改 $ git diff readme.txt ,修改後跟上面是同樣的經過$ git add readme.tx,$ git commit -m "wrote a readme file" 提交修改

提交後,咱們再用git status命令看看倉庫的當前狀態:

$ git status

(1) 版本回退

若提交了多個版本,咱們須要回退到指定的版本,首先咱們查看總共有多少個版本,經過命令 $ git log ,$ git log顯示的信息比較全,比較眼花繚亂,可使用 命令$ git log --pretty=oneline 顯示簡短信息

首先,Git必須知道當前版本是哪一個版本,在Git中,用HEAD表示當前版本,也就是最新的提交,上一個版本就是HEAD^,上上一個版本就是HEAD^^,若是往上多的話寫成HEAD~數字

$ git reset --hard HEAD^   //回到上一個版本

這時最新的那個版本經過命令 $ git log 查看已經不存在了,若是須要穿梭回來須要找到commit id

git reflog用來記錄你的每一次命令:$ git reflog

(2)工做區和暫存區

工做區(Working Directory)就是你在電腦裏能看到的目錄,好比個人learngit文件夾就是一個工做區:

版本庫(Repository)

工做區有一個隱藏目錄.git,這個不算工做區,而是Git的版本庫。

Git的版本庫裏存了不少東西,其中最重要的就是稱爲stage(或者叫index)的暫存區,還有Git爲咱們自動建立的第一個分支master,以及指向master的一個指針叫HEAD。

前面講了咱們把文件往Git版本庫裏添加的時候,是分兩步執行的:

第一步是用git add把文件添加進去,實際上就是把文件修改添加到暫存區;

第二步是用git commit提交更改,實際上就是把暫存區的全部內容提交到當前分支。

每次修改,若是不add到暫存區,那就不會加入到commit中。

(3)撤銷修改

一、未add到暫存區,只在工做區  $ git checkout -- readme.txt
2 、git add到暫存區了:慶幸的是,在commit以前,Git一樣告訴咱們,用命令git reset HEAD file能夠把暫存區的修改撤銷掉(unstage),從新放回工做區:
git reset HEAD readme.txt
git checkout -- readme.txt 丟棄工做區的修改
三、如今,假設你不但改錯了東西,還從暫存區提交到了版本庫,怎麼辦呢?還記得版本回退一節嗎?能夠回退到上一個版本。刪除並提交後能夠經過 $ git reset --hard HEAD^回退到刪除前

(4)刪除文件

通常狀況下,你一般直接在文件管理器中把沒用的文件刪了,或者用rm命令刪了:

$ rm test.txt

如今你有兩個選擇,一是確實要從版本庫中刪除該文件,那就用命令git rm刪掉,而且git commit: 

$ git rm test.txt
$ git commit -m "remove test.txt"

如今,文件就從版本庫中被刪除了。 

另外一種狀況是刪錯了,由於版本庫裏還有呢,因此能夠很輕鬆地把誤刪的文件恢復到最新版本:

$ git checkout -- test.txt

四、遠程倉庫

自行註冊GitHub帳號。因爲你的本地Git倉庫和GitHub倉庫之間的傳輸是經過SSH加密的,因此,須要一點設置,建立SSH Key ,cd 切換到learngit,經過命令

$ ssh-keygen -t rsa -C "youremail@example.com"

 使用默認值不停的回車確認,會在C:\Users\Administrator文件夾裏生成.ssh目錄,裏面有id_rsaid_rsa.pub兩個文件,這兩個就是SSH Key的祕鑰對,id_rsa是私鑰,不能泄露出去,id_rsa.pub是公鑰,能夠放心地告訴任何人。而後打開GitHub網站,進入setting-SSH and GPG keys頁面,點「Add SSH Key」,填上任意Title,在Key文本框裏粘貼id_rsa.pub文件的內容,就有了本身的遠程倉庫。

(1)添加遠程庫

如今的情景是,你已經在本地建立了一個Git倉庫後,又想在GitHub建立一個Git倉庫,而且讓這兩個倉庫進行遠程同步,這樣,GitHub上的倉庫既能夠做爲備份,又可讓其餘人經過該倉庫來協做,真是一舉多得。

一、登陸GitHub,在右上角的+裏面有個New repository,在Repository name填入learngit,其餘保持默認設置,點擊「Create repository」按鈕,就成功地建立了一個新的Git倉庫:

二、在本地的learngit倉庫下運行命令:

$ git remote add origin git@github.com:tianyawhl123/learngit.git

添加後,遠程庫的名字就是origin,這是Git默認的叫法,也能夠改爲別的,可是origin這個名字一看就知道是遠程庫。

三、就能夠把本地庫的全部內容推送到遠程庫上:

$ git push -u origin master

 把本地庫的內容推送到遠程,用git push命令,其實是把當前分支master推送到遠程。

因爲遠程庫是空的,咱們第一次推送master分支時,加上了-u參數,Git不但會把本地的master分支內容推送的遠程新的master分支,還會把本地的master分支和遠程的master分支關聯起來,在之後的推送或者拉取時就能夠簡化命令。

從如今起,只要本地做了提交,就能夠經過命令:

$ git push origin master

(2) 從遠程庫克隆

在建立遠程庫的時候勾選Initialize this repository with a README,這樣GitHub會自動爲咱們建立一個README.md文件。建立完畢後,能夠看到README.md文件:

如今,遠程庫已經準備好了,下一步是用命令git clone克隆一個本地庫:

$ git clone git@github.com:michaelliao/gitskills.git

五、分支管理

(1) 建立與合併分支

首先,咱們建立dev分支,而後切換到dev分支:

$ git checkout -b dev

git checkout命令加上-b參數表示建立並切換,至關於如下兩條命令:

$ git branch dev
$ git checkout dev

 而後,用git branch命令查看當前分支:

$ git branch

而後提交:

$ git add readme.txt 
$ git commit -m "branch test"

 如今,dev分支的工做完成,咱們就能夠切換回master分支:

$ git checkout master

如今,咱們把dev分支的工做成果合併到master分支上:

$ git merge dev

 合併完成後,就能夠放心地刪除dev分支了:

$ git branch -d dev

(2) 解決衝突

新建分支並指向此分支

$ git checkout -b feature1

修改readme.txt最後一行內容並在feature1分支上add和commit

切換到master分支:

$ git checkout master

也修改readme.txt的最後一行,並在master分支上add和commit

如今master分支和feature1分支各自都分別有新的提交

此時在master分支上合併feature1會出現衝突

$ git merge feature1

Git用<<<<<<<=======>>>>>>>標記出不一樣分支的內容,咱們修改後後保存,再add和commit提交

用帶參數的git log也能夠看到分支的合併狀況:

$ git log --graph --pretty=oneline --abbrev-commit

最後刪除feature1分支

$ git branch -d feature1

(3) 分支管理策略

在實際開發中,咱們應該按照幾個基本原則進行分支管理:

首先,master分支應該是很是穩定的,也就是僅用來發布新版本,平時不能在上面幹活;

那在哪幹活呢?幹活都在dev分支上,也就是說,dev分支是不穩定的,到某個時候,好比1.0版本發佈時,再把dev分支合併到master上,在master分支發佈1.0版本;

你和你的小夥伴們每一個人都在dev分支上幹活,每一個人都有本身的分支,時不時地往dev分支上合併就能夠了。

一般,合併分支時,若是可能,Git會用Fast forward模式,但這種模式下,刪除分支後,會丟掉分支信息。

若是要強制禁用Fast forward模式,Git就會在merge時生成一個新的commit,這樣,從分支歷史上就能夠看出分支信息。

合併dev分支,請注意--no-ff參數,表示禁用Fast forward

$ git merge --no-ff -m "merge with no-ff" dev

(4) Bug分支

軟件開發中,bug就像屢見不鮮同樣。有了bug就須要修復,在Git中,因爲分支是如此的強大,因此,每一個bug均可以經過一個新的臨時分支來修復,修復後,
合併分支,而後將臨時分支刪除。

當你接到一個修復一個代號101的bug的任務時,很天然地,你想建立一個分支issue-101來修復它,可是,等等,當前正在dev上進行的工做尚未提交:
並非你不想提交,而是工做只進行到一半,還無法提交,預計完成還需1天時間。可是,必須在兩個小時內修復該bug,怎麼辦?

幸虧,Git還提供了一個stash功能,能夠把當前工做現場「儲藏」起來,等之後恢復現場後繼續工做:
$ git stash,如今,用git status查看工做區,就是乾淨的(除非有沒有被Git管理的文件),所以能夠放心地建立分支來修復bug。

首先肯定要在哪一個分支上修復bug,假定須要在master分支上修復,就從master建立臨時分支:
$ git checkout master
$ git checkout -b issue-101
如今修復bug,須要把「Git is free software ...」改成「Git is a free software ...」,而後提交:

$ git add readme.txt 
$ git commit -m "fix bug 101"
修復完成後,切換到master分支,並完成合並,最後刪除issue-101分支:

$ git checkout master
$ git merge --no-ff -m "merged bug fix 101" issue-101
$ git branch -d issue-101
是時候接着回到dev分支幹活了!
$ git checkout dev

工做區是乾淨的,剛纔的工做現場存到哪去了?用git stash list命令看看:

$ git stash list
工做現場還在,Git把stash內容存在某個地方了,可是須要恢復一下,有兩個辦法:

一是用git stash apply恢復,可是恢復後,stash內容並不刪除,你須要用git stash drop來刪除;

另外一種方式是用git stash pop,恢復的同時把stash內容也刪了:

(5)多人協做

當你從遠程倉庫克隆時,實際上Git自動把本地的master分支和遠程的master分支對應起來了,而且,遠程倉庫的默認名稱是origin。

要查看遠程庫的信息,用git remote:

或者,用git remote -v顯示更詳細的信息:

$ git remote -v
origin  git@github.com:michaelliao/learngit.git (fetch)
origin  git@github.com:michaelliao/learngit.git (push)
上面顯示了能夠抓取和推送的origin的地址。若是沒有推送權限,就看不到push的地址。

推送分支

推送分支,就是把該分支上的全部本地提交推送到遠程庫。推送時,要指定本地分支,這樣,Git就會把該分支推送到遠程庫對應的遠程分支上:$ git push origin master
若是要推送其餘分支,好比dev,就改爲:$ git push origin dev
可是,並非必定要把本地分支往遠程推送,那麼,哪些分支須要推送,哪些不須要呢?

master分支是主分支,所以要時刻與遠程同步;

dev分支是開發分支,團隊全部成員都須要在上面工做,因此也須要與遠程同步;

bug分支只用於在本地修復bug,就不必推到遠程了,除非老闆要看看你每週到底修復了幾個bug;

feature分支是否推到遠程,取決於你是否和你的小夥伴合做在上面開發。

抓取分支

多人協做時,你們都會往master和dev分支上推送各自的修改。

如今,模擬一個你的小夥伴,能夠在另外一臺電腦(注意要把SSH Key添加到GitHub)或者同一臺電腦的另外一個目錄下克隆:

$ git clone git@github.com:michaelliao/learngit.git
當你的小夥伴從遠程庫clone時,默認狀況下,你的小夥伴只能看到本地的master分支。不信能夠用git branch命令看看:

$ git branch
* master
如今,你的小夥伴要在dev分支上開發,就必須建立遠程origin的dev分支到本地,因而他用這個命令建立本地dev分支:$ git checkout -b dev origin/dev
如今,他就能夠在dev上繼續修改,而後,時不時地把dev分支push到遠程:

$ git add readme.txt       $ git commit -m "add /usr/bin/env"
$ git push origin dev

 你的小夥伴已經向origin/dev分支推送了他的提交,而碰巧你也對一樣的文件做了修改,並試圖推送:

$ git add hello.py 
$ git commit -m "add coding: utf-8"
$ git push origin dev

推送失敗,由於你的小夥伴的最新提交和你試圖推送的提交有衝突,解決辦法也很簡單,Git已經提示咱們,先用git pull把最新的提交從origin/dev抓下來,而後,在本地合併,解決衝突,再推送:

$ git pull
git pull也失敗了,緣由是沒有指定本地dev分支與遠程origin/dev分支的連接,根據提示,設置dev和origin/dev的連接:

$ git branch --set-upstream dev origin/dev
Branch dev set up to track remote branch dev from origin.
再pull:

$ git pull
Auto-merging hello.py
CONFLICT (content): Merge conflict in hello.py
Automatic merge failed; fix conflicts and then commit the result.
這回git pull成功,可是合併有衝突,須要手動解決,解決的方法和分支管理中的解決衝突徹底同樣。解決後,提交,再push:

$ git add hello.py       $ git commit -m "merge & fix hello.py"
$ git push origin dev

 所以,多人協做的工做模式一般是這樣:

首先,能夠試圖用git push origin branch-name推送本身的修改;

若是推送失敗,則由於遠程分支比你的本地更新,須要先用git pull試圖合併;

若是合併有衝突,則解決衝突,並在本地提交;

沒有衝突或者解決掉衝突後,再用git push origin branch-name推送就能成功!

若是git pull提示「no tracking information」,則說明本地分支和遠程分支的連接關係沒有建立,用命令git branch --set-upstream branch-name origin/branch-name。

這就是多人協做的工做模式,一旦熟悉了,就很是簡單。

(6)標籤管理

在Git中打標籤很是簡單,首先,切換到須要打標籤的分支上:

$ git branch

$ git checkout master
而後,敲命令git tag <name>就能夠打一個新標籤:$ git tag v1.0
能夠用命令git tag查看全部標籤:$ git tag
默認標籤是打在最新提交的commit上的。有時候,若是忘了打標籤,好比,如今已是週五了,但應該在週一打的標籤沒有打,怎麼辦?

方法是找到歷史提交的commit id,而後打上就能夠了:

$ git log --pretty=oneline --abbrev-commit

比方說要對add merge此次提交打標籤,它對應的commit id是6224937,敲入命令:

$ git tag v0.9 6224937
再用命令git tag查看標籤:

$ git tag
v0.9
v1.0
注意,標籤不是按時間順序列出,而是按字母排序的。能夠用git show <tagname>查看標籤信息:

$ git show v0.9

還能夠建立帶有說明的標籤,用-a指定標籤名,-m指定說明文字:

$ git tag -a v0.1 -m "version 0.1 released" 3628164
小結

命令git tag <name>用於新建一個標籤,默認爲HEAD,也能夠指定一個commit id;

git tag -a <tagname> -m "blablabla..."能夠指定標籤信息;

git tag -s <tagname> -m "blablabla..."能夠用PGP簽名標籤;

命令git tag能夠查看全部標籤。

操做標籤
若是標籤打錯了,也能夠刪除:$ git tag -d v0.1
由於建立的標籤都只存儲在本地,不會自動推送到遠程。因此,打錯的標籤能夠在本地安全刪除。

若是要推送某個標籤到遠程,使用命令git push origin <tagname>:$ git push origin v1.0

或者,一次性推送所有還沒有推送到遠程的本地標籤:

$ git push origin --tags
若是標籤已經推送到遠程,要刪除遠程標籤就麻煩一點,先從本地刪除:

$ git tag -d v0.9

而後,從遠程刪除。刪除命令也是push,可是格式以下:

$ git push origin :refs/tags/v0.9

要看看是否真的從遠程庫刪除了標籤,能夠登錄GitHub查看。

標籤管理小結

命令git push origin <tagname>能夠推送一個本地標籤;

命令git push origin --tags能夠推送所有未推送過的本地標籤;

命令git tag -d <tagname>能夠刪除一個本地標籤;

命令git push origin :refs/tags/<tagname>能夠刪除一個遠程標籤。

相關文章
相關標籤/搜索