天天看點

Git學習總結一、Git本地倉庫相關操作二、遠端倉庫三、标簽管理四、參考資料傳送門

Git學習筆記

文章目錄

    • Git學習筆記
  • 一、Git本地倉庫相關操作
  • 二、遠端倉庫
  • 三、标簽管理
  • 四、參考資料傳送門

一、Git本地倉庫相關操作

  1. Linux環境的安裝

sudo apt-get install git

  1. 指定機器使用者和Email位址

git config --global user.name "使用者名"

git config --global user.email "[email protected]"

  1. 建立git倉庫

cd /d/DATA/mkdir RepoLearn ##建立某個目錄 git init ##初始化

  1. 添加檔案到版本庫

git add oneText.txt

warning: LF will be replaced by CRLF in oneText.txt. The file will have its original line endings in your working directory

出現警告:windows中換行符為CRLF,linux中換行符為LF,可禁用轉換

git config --global core.autocrlf false

注:
  • core.autocrlf為true時,将add的所有文本各行末尾中的CRLF轉為LF,本地checkout時轉回CRLF。警惕此設定可能影響二進制檔案的上傳。
  • core.autocrlf為false時,line endings 不作修改,文本檔案保持原樣。
  • core.autocrlf為input時,git把add檔案的CRLF全部轉為LF,checkout時依舊為LF。
  1. 送出到版本庫中git commit -m "更新消息"
$ git commit -m "add one file"
[master (root-commit) 453d52c] add one file 
  Committer: jinsefm <[email protected]>
  Your name and email address were configured automatically basedon your username and hostname. Please check that they are accurate.You can suppress this message by setting them explicitly:    
	  git config --global user.name "Your Name"    
	  git config --global user.email [email protected]
  After doing this, you may fix the identity used for this commit with:    
	  git commit --amend --reset-author
  1 file changed, 1 insertion(+) 
  create mode 100644 learn.txt    
           
  1. 檢視倉庫目前狀态git status
$ git status
On branch master
Changes not staged for commit:  
	(use "git add <file>..." to update what will be committed) 
	(use "git checkout -- <file>..." to discard changes in working directory)        
			modified:   learn.txt
no changes added to commit (use "git add" and/or "git commit -a")
           

提示檔案已修改,使用以下指令檢視修改内容,可以看出learn.txt增加了一行

  1. 對比工作區與暫存區的檔案内容git diff learn.txt
$ git diff learn.txt
diff --git a/learn.txt b/learn.txt
index c073ff2..04454d6 100644
--- a/learn.txt
+++ b/learn.txt
@@ -1 +1,2 @@ 
 Git is a free software.
+Git is a distributed version control system.
           

再次送出前先add.

$ git add learn.txt
$ git commit -m "add one line"
[master 10ab3ff] add one line
 Committer: chen<[email protected]>
 Your name and email address were configured automatically basedon your username and hostname. Please check that they are accurate.You can suppress this message by setting them explicitly:    
	 git config --global user.name "Your Name"    
	 git config --global user.email [email protected]
After doing this, you may fix the identity used for this commit with:    
		git commit --amend --reset-author 
1 file changed, 1 insertion(+)
$ git status
On branch master
nothing to commit, working tree clean
           
  1. 檢視從最近到最遠送出的曆史記錄 git log
$ git log
commit 10ab3ff547b3ddb89c5ddfd2ba134c6d443848dd (HEAD -> master)
Author: chen <[email protected]>
Date:   Tue Nov 13 15:19:30 2018 +0800    
	add one line
commit 453d52cfdcd4822d9cf7663843e1f23145a21504
Author: chen <[email protected]>
Date:   Tue Nov 13 14:55:58 2018 +0800    
           

add one file加–pretty=oneline一行顯示

$ git log --pretty=oneline
10ab3ff547b3ddb89c5ddfd2ba134c6d443848dd (HEAD -> master)  add one line
453d52cfdcd4822d9cf7663843e1f23145a21504  add one file
           
  1. 版本回退

Git中,使用HEAD表示目前版本,上一版本記為 HEAD,上上版本記為HEAD^,往上100個版本記為HEAD~100

$ git reset --hard HEAD^   ##回退到上一個版本
HEAD is now at 453d52c add one file
$ cat learn.txt
Git is a free software.
$ git log
commit 453d52cfdcd4822d9cf7663843e1f23145a21504 (HEAD -> master)
Author: chen <[email protected]>
Date:   Tue Nov 13 14:55:58 2018 +0800    
		add one file
           

回到新版本,可用commitID代替,如下指令10ab3為最新版本的commitID的前五位(輸多少位不限)

$ git reset --hard 10ab3
HEAD is now at 10ab3ff add one line
$ git reflog  ##檢視指令的操作曆史記錄
10ab3ff (HEAD -> master) HEAD@{0}: reset: moving to 10ab3
453d52c HEAD@{1}: reset: moving to HEAD^
10ab3ff (HEAD -> master) HEAD@{2}: commit: add one line
453d52c HEAD@{3}: commit (initial): add one file
           
  1. 工作區與暫存區

工作區是.git目錄所在的父目錄,除了.git目錄以外的區域。

版本庫為.git目錄,包含暫存區Stage和分支Master以及指向master的HEAD指針。

git add 是将工作區内的檔案增加到暫存區中。

git commit是将暫存區的内容送出到目前分支。

某個檔案按以下操作,那麼隻有第一次修改被送出了,第二次修改沒有加到暫存區。

第一次修改–>git add–>第二次修改–>git commit

  1. 對比工作區檔案與版本庫裡邊某版本的差別

git diff HEAD[/^/~num]/版本id前幾位 -- learn.txt

$ git diff HEAD~2 -- learn.txt
diff --git a/learn.txt b/learn.txt
index c073ff2..854d99f 100644
--- a/learn.txt
+++ b/learn.txt
@@ -1 +1,3 @@
-Git is a free software.
+Git is a free software distributed under the GPL.
+Git is a distributed version control system.
+Git has a mutable index called stage.
           
$ git diff 44c1 hello.py
diff --git a/hello.py b/hello.py
index c61e47e..2bbddbf 100644
--- a/hello.py
+++ b/hello.py
@@ -1 +1 @@
-print("HelloWorld!")
+print("HelloWorld,Man!")
           
  1. 丢棄工作區中某檔案的修改
$ git status
On branch master
Changes not staged for commit:  
	(use "git add <file>..." to update what will be committed)  
	(use "git checkout -- <file>..." to discard changes in working directory)        
			modified:   learn.txt
no changes added to commit (use "git add" and/or "git commit -a")
           

git checkout -- learn.txt ##learn.txt 回到最近一次git commit或git add的狀态

例:原狀态–>第一次修改–>[git add]–>第二次修改–>[git checkout --file] --> [git reset HEAD file ##暫存區檔案修改被丢棄]–>[git checkout --file]

第一次checkout:工作區file會恢複到第一次修改的狀态

第二次checkout:工作區file會恢複到原狀态

  1. 丢棄暫存區中某檔案

git reset HEAD file

場景1:當你改亂了工作區某個檔案的内容,想直接丢棄工作區的修改時,用指令git checkout – file。

場景2:當你不但改亂了工作區某個檔案的内容,還添加到了暫存區時,想丢棄修改,分兩步,第一步用指令git reset HEAD ,就回到了場景1,第二步按場景1操作。

場景3:已經送出了不合适的修改到版本庫時,想要撤銷本次送出,參考版本回退,不過前提是沒有推送到遠端庫。

  1. 删除版本庫中的某檔案

git rm file

二、遠端倉庫

  1. 關聯GitHub

<1>建立SSH Key。

在使用者主目錄下檢視是否有.ssh的檔案夾,其中是否包含id_rsa和id_rsa.pub檔案。沒有的話用以下目錄建立:

ssh-keygen -t rsa -C "郵箱位址"

一路回車,使用預設值,中間有一步設定密碼(Enter passphrase)也可.完畢後生成兩份檔案:id_rsa(私鑰)和id_rsa.pub(公鑰)

$ ssh-keygen -t rsa -C "[email protected]"
Generating public/private rsa key pair.
Enter file in which to save the key (/c/Users/chen/.ssh/id_rsa):
Created directory '/c/Users/chen/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /c/Users/chen/.ssh/id_rsa.
Your public key has been saved in /c/Users/chen/.ssh/id_rsa.pub.
The key fingerprint is:SHA256:xxx [email protected]
The key's randomart image is:
+---[RSA 2048]----+
|.*+*o    .       |
|o Oo+ . . .    . |
|.o + o .   o  o  |
|o.. .    .. .. . |
|+o      S o..  +.|
|.*o        oo B o|
|+o=        . = o.|
|.E          o .o.|
|o.         . ....|
+----[SHA256]-----+ 
           

cat ~/.ssh/id_rsa.pub ##檢視公鑰内容

<2>Add SSH keys。

登入GitHub,點選個人頭像,選擇Settings進去,可以看到SSH and GPG keys。

點選New SSHkeys,複制公鑰内容到Keys文本框中,title标題自定義即可。

<3>驗證 SSH keys是否可正常連接配接GitHub伺服器。

ssh -T [email protected]

第一次連接配接報以下資訊,輸入yes即可

The authenticity of host 'github.com (13.229.188.59)' can't be established.
RSA key fingerprint is SHA256:xxxx.
Are you sure you want to continue connecting (yes/no)?
           

之後連又有一個警告

Warning: Permanently added the RSA host key for IP address '13.250.177.223' to the list of known hosts.
Warning: Permanently added the RSA host key for IP address '52.74.223.119' to the list of known hosts.
           

需要将ip添加到host裡邊即可。window在 C:\Windows\System32\drivers\etc\hosts 檔案中添加兩行,linux 則

vim /etc/hosts

,添加兩行

13.250.177.223

52.74.223.119

  1. 本地倉庫與遠端倉庫關聯

在GitHub上建立一個倉庫,輸入倉庫名,其他預設。

關聯遠端倉庫

git remote add origin [email protected]:jinsefm/learnGit.git

git remote add origin [email protected]:path/repo-name.git

把本地倉庫推送到遠端倉庫,第一次推送必須加上-u參數,表示不止推送master分支,還将本地的master分支與遠端的master分支關聯起來,後續推送可簡化指令,不加參數。

git push -u origin master

注:在使用git指令時可能會報以下異常,這是目前路徑不在本地倉庫下,cd指令切換到本地倉庫路徑即可

fatal: not a git repository (or any of the parent directories): .git

  1. 克隆遠端倉庫 git clone [email protected]:jinsefm/HelloWorld.git

git clone [email protected]:path/repo-name.git ##隻克隆了master分支

$ ls
AMOLED/  HelloWorld/  RepoLearn/
$ cd HelloWorld/
$ ls
README.md
           

Git支援多種協定的位址關聯和擷取遠端倉庫,一般使用ssh支援的原生git協定最快,使用https協定每次操作都需要輸入密碼。

三、分支管理

  1. 建立分支 dev

git branch dev

  1. 檢視分支

git branch$ git branch dev* master

  1. 切換到分支dev

git checkout dev$ git branch* dev master

  1. 建立并切換到分支 dev

git checkout -b dev

  1. 把分支dev合并到目前分支

git checkout master ##切換到mater分支git merge dev ##合并dev到目前分支master

  1. 删除分支dev

git branch -d dev

  1. 解決沖突
$ pwd
/d/DATA/HelloWorld
$ ls
README.md
$ cat README.md# gitSkills
$ git checkout master
Switched to branch 'master'Your branch is up to date with 'origin/master'.
$ vim README.md
# gitSkills
create a new branch quick and simple
$ git add README.md
$ git commit -m "add new branch quickly"
[master a0c9169] add new branch quickly
$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.  
	(use "git push" to publish your local commits)
nothing to commit, working tree clean
$ git checkout dev
Switched to branch 'dev'
$ vim README.md
# gitSkills
create a new branch!
$ git add README.md
$ git commit -m "create new branch"
[dev 0eea0da] create new branch
$ git checkout master
$ git merge dev
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.
$ cat README.md
# gitSkills<<<<<<< HEAD
create a new branch quick and simple
=======
create a new branch!
>>>>>>> dev
           

如上,本地倉庫master合并dev分支出現沖突。

最終确認沖突的内容,修改成如下并送出。

$ cat README.md
# gitSkills
create a new branch quickly and simple!
$ git add README.md
$ git commit -m "conflict fixed"
[master 033406c] conflict fixed
           

最後檢視合并情況。

$ git log --graph --pretty=oneline --abbrev-commit
*   033406c (HEAD -> master) conflict fixed
|\
| * 0eea0da (dev) create new branch
* | a0c9169 add new branch quickly
|/
* b6f95c1 (origin/master, origin/HEAD) Initial commit
           

以上merge合并分支是fast forward的模式,如下删除分支後,對比上下曆史記錄中已看不到合并的分支資訊。

$ git branch -d dev
Deleted branch dev (was 0eea0da).
$ git log --graph --pretty=oneline --abbrev-commit
*   033406c (HEAD -> master) conflict fixed
|\
| * 0eea0da create new branch
* | a0c9169 add new branch quickly
|/
* b6f95c1 (origin/master, origin/HEAD) Initial commit
           

合并分支時最好采用–on-ff模式的git merge,這種普通模式可以保留送出記錄中的合并分支資訊。

git merge --on-ff -m "merge information" dev

  1. 分支政策

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

首先,

master

分支應該是非常穩定的,也就是僅用來釋出新版本,平時不能在上面幹活;

那在哪幹活呢?幹活都在

dev

分支上,也就是說,

dev

分支是不穩定的,到某個時候,比如1.0版本釋出時,再把

dev

分支合并到master上,在master分支釋出1.0版本;

你和你的小夥伴們每個人都在dev分支上幹活,每個人都有自己的分支,時不時地往dev分支上合并就可以了。

  1. Bug分支處理

工作中dev分支的任務進行一半,突然接到緊急任務修複bug101,此時需要把dev的工作現場儲藏起來,待bug解決後再恢複dev工作現場。

$ vim hello.py
HelloWorld!
$ ls
hello.py  README.md
$ git stash  ## 此時hello.py 未加到暫存區
No local changes to save
$ git add hello.py
$ git stash  ## 把git-add的儲存起來
Saved working directory and index state WIP on master: 033406c conflict fixed
$ ls         ## 此時hello.py已經被儲藏起來
README.md  
$ git stash list
stash@{0}: WIP on master: 033406c conflict fixed
           
##此時再去做bug修複的任務
$ git checkout master              ## 切換到主分支 master
$ git checkout -b issue-101        ## 在主分支上建立并切換到分支issue-101
$ vim bug101.py
$ git add bug101.py
$ git commit -m "fixed bug 101"    ## 送出修改到分支issue-101
$ git checkout master              
$ git merge --on-ff -m "merge bug fix 101" issue-101 ## 合并分支issue-101 到目前主分支master
$ git branch -d issue-101          ## 删除分支issue-101
$ git checkout dev                 ## 切換到dev分支
$ git status
On branch dev
nothing to commit, working tree clean
$ git stash list
stash@{0}: WIP on master: 033406c conflict fixed                   
$ git stash pop                 ## 恢複之前存儲的進行一半的工作現場
On branch master
Your branch is ahead of 'origin/master' by 3 commits. 
	(use "git push" to publish your local commits)
Changes to be committed:  
	(use "git reset HEAD <file>..." to unstage)        
	new file:   hello.py
Dropped refs/stash@{0} (1dacb13726b35cc29c162d66f934418a72b397a3)  
## stash區的内容被删除,使用git stash apply指令則不删除
$ ls
hello.py  README.md          ## 此時hello.py已經恢複過來了
           

多次stash時,使用以下指令可以指定恢複哪個stash

git stash pop stash@{0} ## stash@{0} 對應stash list 中的第一個id

删除未合并的分支

git branch -D 分支名

  1. 多人協作

git remote -v ##檢視遠端庫資訊

git push origin master ##把本地分支master上所有送出推送到遠端庫origin

git checkout -b dev origin/dev ## 本地建立dev分支并同步遠端dev分支到本地

git branch --set-upstream-to=origin/dev dev ##本地需已有dev分支,但未關聯遠端庫dev分支,可用此指令關聯,并未同步

git checkout dev

git pull ##從遠端分支dev抓取最新的修改

git pull origin dev ##抓取遠端庫的dev分支到本地目前分支,并未将遠端dev分支與本地目前分支關聯

git-rebase -i <startpoint> [endpoint]

-i參數表示進入編輯本地送出的指令,編輯startpoint到endpoint的送出 如 startpoint可輸80930f6或HEAD~6,endpoint 不輸表示目前送出。

$ git log --oneline
7d5b8ee (HEAD -> dev, origin/dev) second edited develop.txt
1042ad0 merge edited develop.txt
c54232c who edited develop.txt
9ddd17c edited develop.txt
615a4c9 create branch& develop note80930f6 (origin/master, origin/HEAD, master) fix conlicts
$ git rebase -i 80930f6
           

按照以下

commands文本

的提示重新對曆史送出進行操作,從80930f6的後一個commit開始到最後一個,前開後閉的區間形式。

pick 615a4c9 create branch& develop note
s    c54232c who edited develop.txt
s    9ddd17c edited develop.txt
pick 7d5b8ee second edited develop.txt

# Rebase 80930f6..7d5b8ee onto 80930f6 (4 commands)
#
# Commands:
# p, pick <commit> = use commit                   ##保留該commit
# r, reword <commit>=use commit, but edit the commit message##修改該commit的注釋
# e, edit <commit> = use commit, but stop for amending    ## 執行到該commit時暫停
# s, squash <commit> = use commit, but meld into previous commit       ## 将該commit與上一個commit合并
# f, fixup <commit> = like "squash", but discard this commit's log message ## 除了s的功能,保留commit的注釋
# x, exec <command> = run command (the rest of the line) using shell          ## 執行shell指令
# d, drop <commit> = remove commit                                                             ##丢棄該commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified). Use -c <commit> to reword the commit message.
## These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
#    However, if you remove everything, the rebase will be aborted.
#
#    
# Note that empty commits are commented out
           

該檔案儲存并退出後會依次順序執行沒有#開頭的指令。若操作的commit中有沖突暫停需要先解決沖突再執行以下指令後繼續進行

git rebase --continue

執行

git rebase --abort

則會全部停止,所有的commands都不會執行。

注:dev|REBASE-i 3/4表示執行到上述

commands文本

的第三個操作

<1>文本沖突直接abort的情況如下:

$ git rebase -i 80930f6
Auto-merging develop.txt
CONFLICT (content): Merge conflict in develop.txt
error: could not apply 9ddd17c... edited develop.txt
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 9ddd17c... edited develop.txt
[email protected] MINGW64 /d/DATA/HelloWorld2/HelloWorld (dev|REBASE-i 3/4)
$ cat develop.txt
This is  a  developnote!
<<<<<<< HEAD
The file is edited by  JINSEFM.
=======
The file was edited by someone.
>>>>>>> 9ddd17c... edited develop.txt
[email protected] MINGW64 /d/DATA/HelloWorld2/HelloWorld (dev|REBASE-i 3/4)
$ git rebase --abort
[email protected] MINGW64 /d/DATA/HelloWorld2/HelloWorld (dev)
$ cat develop.txt       
This is  a  developnote!
The file is edited by  JINSEFM.
edittime:2018-11-15
           

<2>解決包含Merge-Commit中的文本沖突的情況如下:

[email protected] MINGW64 /d/DATA/HelloWorld2/HelloWorld (dev)
$ git rebase -i 80930f6
Auto-merging develop.txt
CONFLICT (content): Merge conflict in develop.txt
error: could not apply 9ddd17c... edited develop.txt
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 9ddd17c... edited develop.txt
[email protected] MINGW64 /d/DATA/HelloWorld2/HelloWorld (dev|REBASE-i 3/4)
$ vim develop.txt
[email protected] MINGW64 /d/DATA/HelloWorld2/HelloWorld (dev|REBASE-i 3/4)
$ cat develop.txt
This is  a  developnote!
The file is edited by  JINSEFM.
[email protected] MINGW64 /d/DATA/HelloWorld2/HelloWorld (dev|REBASE-i 3/4)
$ git add develop.txt
           
# This is a combination of 2 commits.
# This is the 1st commit message:
create branch& develop note
# This is the commit message #2:

who edited develop.txt

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Thu Nov 15 11:03:07 2018 +0800# Committer: chen <[email protected]>
#
# interactive rebase in progress; onto 80930f6
# Last commands done (3 commands done):
#    squash c54232c who edited develop.txt
#    squash 9ddd17c edited develop.txt
# Next command to do (1 remaining command):
#    pick 7d5b8ee second edited develop.txt
# You are currently rebasing branch 'dev' on '80930f6'.
#
# Changes to be committed:
#    new file:   develop.txt
#
           
$ git rebase --continue  ##解決文本沖突後繼續執行rebase
[detached HEAD 3397510] create branch& develop note 
	Date: Thu Nov 15 11:03:07 2018 +0800 
	Committer: chen <c[email protected]>
Successfully rebased and updated refs/heads/dev.
           

檢視log,發現中間兩個commit已經被合并成一個了。

$ git log
commit e181daa611f5f212a2f626ef302d19dfaf387b75 (HEAD -> dev)
Author: chen <[email protected]>Date:   Fri Nov 16 11:00:48 2018 +0800   
	 second edited develop.txt
commit 339751018c5569352c5f32906b913a2c5038a5df
 Author: chen <[email protected]>Date:   Thu Nov 15 11:03:07 2018 +0800    
	 create branch& develop note    
	 who edited develop.txt
commit 80930f6ae70df682f8f6c6d422bc3198b44dff98 (origin/master, origin/HEAD, master)
Merge: 3c79c73 44c1d94
Author: chen <[email protected]>
Date:   Thu Nov 15 10:21:42 2018 +0800    
	fix conlicts
$ cat develop.txt
This is  a  developnote!
The file is edited by  JINSEFM.
edittime:2018-11-15
           

三、标簽管理

  1. 添加标簽

git tag v1.0 ## 給目前分支目前送出打上标簽 v1.0

git tag v1.1 e181da ##給e181da版本加上标簽v1.1

git tag -a v1.2 -m "realease 1.2 version" [commitID] ##給【commitID/目前版本】添加标簽v1.2,同時指定标簽資訊為realease 1.2 version

  1. 檢視所有标簽

git tag

  1. 删除标簽

git tag -d v1.0 ##删除标簽v1.0

git push origin :refs/tags/v1.0 ##先删本地标簽,再執行此指令删除遠端标簽v1.0

  1. 推送本地标簽到遠端庫

git push origin v1.0 ## 把v1.0标簽推送到遠端

git push origin --tags ##推送全部尚未推送到遠端的本地标簽

四、參考資料傳送門

廖雪峰老師的Git教程

Git官方文檔

螞蟻部落Git教程

git-cheat-sheet