Git基本操作總結
建立版本庫
git init #初始化本地版本庫
git add fileName #新增檔案到暫存區,檔案可一次新增多個
git commit -m "description" #提交到倉庫
####
$ 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: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
比較倉庫與工作區檔案差別
$ git diff readme.txt
diff --git a/readme.txt b/readme.txt
index 46d49bf..9247db6 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,2 +1,2 @@
-Git is a version control system.
+Git is a distributed version control system.
Git is free software.
比較檔案需要兩個檔案在一起比較,idea可以比較當前檔案與不同提交歷史檔案、與其他目錄檔案、與不同分支、本地不同修改時刻檔案的差別。
檢視提交記錄
$ git log
commit 1094adb7b9b3807259d8cb349e7df1d4d6477073 (HEAD -> master)
Author: Michael Liao <[email protected]>
Date: Fri May 18 21:06:15 2018 +0800
append GPL
commit e475afc93c209a690c39c13a46716e8fa000c366
Author: Michael Liao <[email protected]>
Date: Fri May 18 21:03:36 2018 +0800
add distributed
commit eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0
Author: Michael Liao <[email protected]>
Date: Fri May 18 20:59:18 2018 +0800
wrote a readme file
$ git log --pretty=oneline #簡化輸出
1094adb7b9b3807259d8cb349e7df1d4d6477073 (HEAD -> master) append GPL
e475afc93c209a690c39c13a46716e8fa000c366 add distributed
eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0 wrote a readme file
版本回退
$ git reset --hard HEAD^ #回退到上一個版本
HEAD is now at e475afc add distributed
$ git reset --hard 1094a #回退到指定commit id號提交
HEAD is now at 83b0afe append GPL
git內部有個HEAD指標,指向不同分支,如master、release、feature分支,分支指向提交,git管理的是修改,而不是檔案。
檢視歷史命令
$ git reflog #可以找到所有commit id以及解決衝突、切換分支等歷史記錄
e475afc HEAD@{1}: reset: moving to HEAD^
1094adb (HEAD -> master) HEAD@{2}: commit: append GPL
e475afc HEAD@{3}: commit: add distributed
eaadf4e HEAD@{4}: commit (initial): wrote a readme file
工作區、版本庫、暫存區、分支的概念
工作區:就是電腦裡能看到的目錄
版本庫:工作區有一個隱藏目錄.git,這個不算工作區,而是git的版本庫。
暫存區:版本庫裡存了很多東西,其中最重要的就是稱為stage的暫存區,還有git為我們自動建立的第一個分支master,以及指向master的一個指標叫 HEAD。
往git版本庫裡新增檔案分兩步執行的:
-
用git add把檔案新增進去,實際上把檔案修改新增到暫存區;
-
用git commit提交更改,實際上把暫存區的所有內容提交到當前分支。
可以把需要提交的檔案修改統統放到暫存區,然後一次性提交暫存區的所有修改。
撤銷修改
-
已提交到分支,參見版本回退一節。
-
修改後新增到暫存區:
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: test.txt
bijingwang@DESKTOP-PSO1H64 MINGW64 /d/test02/gitee/git22/git-test (master)
$ git restore --staged test.txt #將暫存區的修改撤銷掉
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: test.txt
no changes added to commit (use "git add" and/or "git commit -a")
$ git restore test.txt #撤銷工作區修改
-
如果提交到暫存區後又修改了,同2
刪除檔案
工作區刪除->提交到暫存區->提交到版本庫
$ rm test.txt
$ git rm test.txt #或者用git add命令
rm 'test.txt'
$ git commit -m "remove test.txt"
[master d46f35e] remove test.txt
1 file changed, 1 deletion(-)
delete mode 100644 test.txt
刪錯了,用git reset可以恢復。
新增遠端庫
一開始在github或者私有git伺服器建遠端倉庫時,可以在本機從遠端倉庫克隆,也可以把一個已有的本地倉庫與之關聯。
$ git remote add origin [email protected]:michaelliao/learngit.git #將一個已有的本地倉庫與遠端倉庫建立關聯 $ git clone [email protected]:michaelliao/gitskills.git #克隆 Cloning into 'gitskills'... remote: Counting objects: 3, done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 3 Receiving objects: 100% (3/3), done.
建立分支
HEAD嚴格來說不是指向提交,而是指向master,master才是指向提交的。
-
檢視當前分支
$ git branch #當前分支前面會標一個*號 * dev master
-
建立、切換分支
$ git switch -c dev #建立並切換到dev分支 $ git switch master #切換到dev分支
-
合併分支
$ git merge dev #將dev分支合到當前分支上 Updating d46f35e..b17d20e Fast-forward #無衝突快進模式,有衝突需解決衝突再合併 readme.txt | 1 + 1 file changed, 1 insertion(+) $ git branch -d dev #合併後刪除dev分支 Deleted branch dev (was b17d20e).
解決衝突
$ git merge feature1 Auto-merging readme.txt CONFLICT (content): Merge conflict in readme.txt #說明在readme.txt發生衝突 Automatic merge failed; fix conflicts and then commit the result. $ git status On branch master Your branch is ahead of 'origin/master' by 2 commits. #比遠端領先兩個提交 (use "git push" to publish your local commits) You have unmerged paths. (fix conflicts and run "git commit") #解決衝突後提交完成合並 (use "git merge --abort" to abort the merge) #放棄合併 Unmerged paths: (use "git add <file>..." to mark resolution) both modified: readme.txt #衝突檔案 no changes added to commit (use "git add" and/or "git commit -a")
此時衝突檔案變為:
Git is a distributed version control system. Git is free software distributed under the GPL. Git has a mutable index called stage. Git tracks changes of files. <<<<<<< HEAD Creating a new branch is quick & simple. ======= #分割衝突 Creating a new branch is quick AND simple. >>>>>>> feature1
需要選擇保留的內容,刪除不需要的。對於java檔案,不建議在notepad上操作,涉及到依賴,notepad不會自動引入或刪除依賴。
合併後如圖:
$ git log --graph --pretty=oneline --abbrev-commit * cf810e4 (HEAD -> master) conflict fixed #這裡解決衝突,兩個分支連線 |\ | * 14096d0 (feature1) AND simple * | 5dc6824 & simple |/ * b17d20e branch test * d46f35e (origin/master) remove test.txt * b84166e add test.txt * 519219b git tracks changes * e43a48b understand how stage works * 1094adb append GPL * e475afc add distributed * eaadf4e wrote a readme file
保留現場
如果不提交就切換到其他分支,會導致修改丟失。可以將當前工作現場“儲藏”起來,等以後恢復現場後繼續工作(不常用):
$ git stash #保留現場,進棧 Saved working directory and index state WIP on dev: f52c633 add merge $ git stash list #棧裡有多個 stash@{0}: WIP on dev: f52c633 add merge $ git stash pop #恢復現場 On branch dev Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: hello.py 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: readme.txt Dropped refs/stash@{0} (5d677e2ee266f39ea296182fb2354265b91b3b2a) $ git stash apply stash@{0} #指定恢復“哪個現場” $ git cherry-pick 4c805e2 #從其他分支複製提交,有可能衝突 [master 1d4b803] fix bug 101 1 file changed, 1 insertion(+), 1 deletion(-)
刪除分支
新建的分支修改後提交,一般需要合到其他分支才能合併。
$ git branch -d feature-vulcan #無法刪除 error: The branch 'feature-vulcan' is not fully merged. #提示還沒合併 If you are sure you want to delete it, run 'git branch -D feature-vulcan'. $ git branch -D feature-vulcan #-D引數可以刪除 Deleted branch feature-vulcan (was 287773e).
檢視遠端倉庫資訊
$ git remote -v origin [email protected]:michaelliao/learngit.git (fetch) origin [email protected]:michaelliao/learngit.git (push)
推送分支
$ git push origin master #需使本地分支與遠端分支對應起來
建立本地分支與遠端分支關係
$ git branch #當你從遠端倉庫克隆時,實際上Git自動把本地的master分支和遠端的master分支對應起來了,並且,遠端倉庫的預設名稱 #是origin。 * master $ git branch --set-upstream-to=origin/dev dev #方法1:本地建立分支dev,然後設定dev與遠端dev的連結 Branch 'dev' set up to track remote branch 'dev' from 'origin'. $ git switch -c feature origin/feature #方法2:建立分支時直接指定與遠端分支的連結 Switched to a new branch 'feature' Branch 'feature' set up to track remote branch 'feature' from 'origin'.
拉取分支
$ git pull #拉取,可能會出現衝突 Auto-merging env.txt CONFLICT (add/add): Merge conflict in env.txt Automatic merge failed; fix conflicts and then commit the result.
合併情形總結
衝突發生在兩個分支對同一個檔案修改,在合併時發生,都是通過選擇保留的內容後提交到分支來解決衝突,此後再對這個檔案修改不會再引起衝突了,除非其他人在你提交前對同一個檔案進行提交
現有feature、release、origin\feature、origin\release四個分支:
feature往origin\feature上合:
合併成功
發生衝突,git原生命令拒絕合併,提示先pull再push。idea整合工具馬上讓你解決衝突,並將feature落後origin/feature上的提交合到feature。
origin/feature---》feature:
拉取成功
衝突,解決衝突提交即為解決衝突。idea解決衝突後不需要手動提交。
origin/feature---->>origin/release:
merge成功
衝突,解決衝突後將origin/feature落後origin/release上的提交合到origin/feature。此類情形,不建議遠端解決衝突,可以本地feature-->>release,原生的git merge和idea操作不會在解決衝突後進行release-->feature汙染feature分支。
idea解決衝突介面
左右兩邊為衝突雙方,中間為最終保留結果,可以保留一方,也可以兩個都保留。