1. 程式人生 > 實用技巧 >Git基本操作總結

Git基本操作總結

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版本庫裡新增檔案分兩步執行的:

  1. 用git add把檔案新增進去,實際上把檔案修改新增到暫存區;

  2. 用git commit提交更改,實際上把暫存區的所有內容提交到當前分支。

可以把需要提交的檔案修改統統放到暫存區,然後一次性提交暫存區的所有修改。

撤銷修改

  1. 已提交到分支,參見版本回退一節。

  2. 修改後新增到暫存區:

$ 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 #撤銷工作區修改
  1. 如果提交到暫存區後又修改了,同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上合:

  1. 合併成功

  2. 發生衝突,git原生命令拒絕合併,提示先pull再push。idea整合工具馬上讓你解決衝突,並將feature落後origin/feature上的提交合到feature。

  • origin/feature---》feature:

  1. 拉取成功

  2. 衝突,解決衝突提交即為解決衝突。idea解決衝突後不需要手動提交。

  • origin/feature---->>origin/release:

  1. merge成功

  2. 衝突,解決衝突後將origin/feature落後origin/release上的提交合到origin/feature。此類情形,不建議遠端解決衝突,可以本地feature-->>release,原生的git merge和idea操作不會在解決衝突後進行release-->feature汙染feature分支。


idea解決衝突介面

左右兩邊為衝突雙方,中間為最終保留結果,可以保留一方,也可以兩個都保留。