Git學習筆記
文章目錄
-
- Git學習筆記
- 一、Git本地倉庫相關操作
- 二、遠端倉庫
- 三、标簽管理
- 四、參考資料傳送門
一、Git本地倉庫相關操作
- Linux環境的安裝
sudo apt-get install git
- 指定機器使用者和Email位址
git config --global user.name "使用者名"
git config --global user.email "[email protected]"
- 建立git倉庫
cd /d/DATA/mkdir RepoLearn ##建立某個目錄 git init ##初始化
- 添加檔案到版本庫
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。
- 送出到版本庫中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
- 檢視倉庫目前狀态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增加了一行
- 對比工作區與暫存區的檔案内容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
- 檢視從最近到最遠送出的曆史記錄 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
- 版本回退
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
- 工作區與暫存區
工作區是.git目錄所在的父目錄,除了.git目錄以外的區域。
版本庫為.git目錄,包含暫存區Stage和分支Master以及指向master的HEAD指針。
git add 是将工作區内的檔案增加到暫存區中。
git commit是将暫存區的内容送出到目前分支。
某個檔案按以下操作,那麼隻有第一次修改被送出了,第二次修改沒有加到暫存區。
第一次修改–>git add–>第二次修改–>git commit
- 對比工作區檔案與版本庫裡邊某版本的差別
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!")
- 丢棄工作區中某檔案的修改
$ 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會恢複到原狀态
- 丢棄暫存區中某檔案
git reset HEAD file
場景1:當你改亂了工作區某個檔案的内容,想直接丢棄工作區的修改時,用指令git checkout – file。
場景2:當你不但改亂了工作區某個檔案的内容,還添加到了暫存區時,想丢棄修改,分兩步,第一步用指令git reset HEAD ,就回到了場景1,第二步按場景1操作。
場景3:已經送出了不合适的修改到版本庫時,想要撤銷本次送出,參考版本回退,不過前提是沒有推送到遠端庫。
- 删除版本庫中的某檔案
git rm file
二、遠端倉庫
- 關聯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
- 本地倉庫與遠端倉庫關聯
在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
- 克隆遠端倉庫 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協定每次操作都需要輸入密碼。
三、分支管理
- 建立分支 dev
git branch dev
- 檢視分支
git branch$ git branch dev* master
- 切換到分支dev
git checkout dev$ git branch* dev master
- 建立并切換到分支 dev
git checkout -b dev
- 把分支dev合并到目前分支
git checkout master ##切換到mater分支git merge dev ##合并dev到目前分支master
- 删除分支dev
git branch -d dev
- 解決沖突
$ 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
- 分支政策
在實際開發中,我們應該按照幾個基本原則進行分支管理:
首先,
master
分支應該是非常穩定的,也就是僅用來釋出新版本,平時不能在上面幹活;
那在哪幹活呢?幹活都在
dev
分支上,也就是說,
dev
分支是不穩定的,到某個時候,比如1.0版本釋出時,再把
dev
分支合并到master上,在master分支釋出1.0版本;
你和你的小夥伴們每個人都在dev分支上幹活,每個人都有自己的分支,時不時地往dev分支上合并就可以了。
- 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 分支名
- 多人協作
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
三、标簽管理
- 添加标簽
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
- 檢視所有标簽
git tag
- 删除标簽
git tag -d v1.0 ##删除标簽v1.0
git push origin :refs/tags/v1.0 ##先删本地标簽,再執行此指令删除遠端标簽v1.0
- 推送本地标簽到遠端庫
git push origin v1.0 ## 把v1.0标簽推送到遠端
git push origin --tags ##推送全部尚未推送到遠端的本地标簽
四、參考資料傳送門
廖雪峰老師的Git教程
Git官方文檔
螞蟻部落Git教程
git-cheat-sheet