git的基本使用流程

關於git的基本理解

git:一種分佈式版本控制系統

git保存的是每一次改動,而不是文件本身。


git有三個區:

工作區(Working Directory)

這個區就是你在電腦上創建項目的地方,文件的編輯修改都在這個區中進行。

暫存區(Stage Area)

暫存區存放的是待提交到repo的修改,當你使用git add命令時,就是把工作區的修改添加到暫存區。

版本庫/倉庫(Git Directory/Repository)

每次使用git commit命令,就是把暫存區中的內容全部提交到repo中。


關於分支:

新建分支默認是master。

master分支應該是一個穩定的,可用的應用,平時不在這個分支上工作。

當要添加新功能時,可從master分支新建一個分支,如feature分支,當新功能完成時,再合併到master分支上,這樣,master分支始終是穩定可用的。

多人合作時,可以每個人在各自的分支上工作,時不時合併到同一個分支上,當功能完善時,再合併到master分支。

分支之間大概是這種感覺(假設A、B兩個人開發):

branches

當master分支上的應用出現bug時,可以在master分支上新建一個bug分支,如issue-101,修復bug後再合併到master分支上,然後刪除bug分支。

基本流程

假設你已經安裝了git

以下考慮最基本的git使用流程,開發時遇到的情況很多,以下流程暫不列出刪除、撤銷、回退的步驟,後面再單獨列出來。

暫不考慮多人合作與遠程repo,後面再補充,因爲了解了怎麼自己玩git,也就明白怎麼跟基友一起玩github了。

因此以下流程都是在本地進行,跟github啥的暫時沒什麼關係。

新建repo->修改文件->添加修改到暫存區->提交修改到repo->創建分支->修改文件->添加修改到暫存區->提交修改到repo->合併分支->解決衝突

創建bug分支->修復bug->合併分支

流程步驟

新建repo

在項目根目錄下使用git init初始化git倉庫

修改文件

我們在項目目錄下新建一個hello.txt文件,裏面輸入內容hello world(注意不要用Windows自帶的記事本創建、編輯)

然後輸入git status,會看到輸出了這些信息:

On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        hello.txt

nothing added to commit but untracked files present (use "git add" to track)

這邊git提示我們有一個Untracked file,可以用git add <file>來添加要提交的文件。

添加修改到暫存區

按照提示,我們輸入git add hello.txt把文件添加到暫存區(使用git add .添加更改過的全部文件)

再次輸入git status,這次看到輸出信息:

On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

        new file:   hello.txt

hello.txt已經被存放到暫存區了

提交修改到repo

使用git commit -m 'add hello.txt'來提交這個文件的更改

輸出信息:

[master (root-commit) 88aa3e8] add hello.txt
 1 file changed, 1 insertion(+)
 create mode 100644 hello.txt

這時候,文件的更改已經提交到repo中。

創建分支

在master分支下:

git checkout -b feature創建並切換到feature分支

創建分支是git branch feature,創建feature分支

切換分支是git checkout feature,切換到feature分支

合併分支

我們切換到feature分支,git checkout feature

打開剛纔的hello.txt

把內容修改成goodbye world

然後用git addgit commit命令提交到repo中

切換到master分支,在hello.txt文件結尾加上一行hello world again,然後提交

這時候,兩個分支各有一個提交(commit)

我們切換到master分支git checkout master

然後把feature分支合併到master分支上,git merge --no-ff -m 'merge feature' feature

這時候會提示有衝突:

Auto-merging hello.txt
CONFLICT (content): Merge conflict in hello.txt
Automatic merge failed; fix conflicts and then commit the result.

git提示我們解決了衝突再把結果commit。

解決衝突

衝突在多人合作中應該是常有的事。

我們打開hello.txt,發現內容變成了這樣

hello world
<<<<<<< HEAD
hello world again
=======
goodbye world
>>>>>>> feature

於是我們把hello.txt修改成:

hello world
goodbye world

然後提交

git add hello.txt
git commit -m 'fix conflict'
[master 40cd928] fix conflict

分支合併成功。

可以用git log --graph --pretty=oneline --abbrev-commit來查看合併的情況

*   40cd928 fix conflict
|\
| * 3cbd4df modified hello.txt
* | a40c0bc add "again"
|/
* 10fb7e4 add hello.txt

log的順序是按時間順序從下到上。

bug分支

假設現在master分支上發現了個bug,需要緊急修復,但你現在正在feature分支上工作

假設現在hello.txt的內容是:

hello world
goodbye world

feature branch unfinished work

現在feature分支上的功能還未完成,無法提交,但是需要修復bug。這時,就需要使用git stash保存工作現場。

於是,在feature分支上,輸入git stash,看到輸出信息:

Saved working directory and index state WIP on feature: 3cbd4df modified hello.txt
HEAD is now at 3cbd4df modified hello.txt

這時候,再輸入git status,發現輸出:

On branch feature
nothing to commit, working tree clean

現場已被保存,打開hello.txt,後面的那句feature branch unfinished work也不見了。

好,現在我們可以切換到master分支,並新建一個bug分支來修復這個bug了。

git checkout master
git checkout -b issue-101

在hello.txt中添加一行issue-101 bug fixed,提交到repo

然後切回master分支,把issue-101分支合並進來。

git add hello.txt
git commit -m 'bug fixed'

git checkout master
git merge --no-ff -m 'merge issue-101' issue-101

輸出信息:

Merge made by the 'recursive' strategy.
 hello.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

合併完成,然後我們回到feature分支繼續工作。

git checkout feature

但是現在hello.txt裏面的內容還是

hello world
goodbye world

我們需要把之前未完成的工作現場恢復過來。

使用git stash list可以查看保存了哪些工作現場:

stash@{0}: WIP on feature: 3cbd4df modified hello.txt

可以看到,這邊只有一條數據,我們可以使用git stash pop來恢復這個現場。

輸出的信息:

On branch feature
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:   hello.txt

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (643bef60d9b9540f66675d2fe1e8d9ad9d35f4fd)

可以看到,hello.txt裏面的feature branch unfinished work又回來了
並且在恢復現場後,Dropped refs/stash@{0} (643bef60d9b9540f66675d2fe1e8d9ad9d35f4fd)
刪除了stash的內容。

如果有多條stash數據,可以用git stash apply來恢復,如

git stash apply stash@{0}

但是用這種方式,stash內容並不會被刪除,如果要刪除某條stash,用git stash drop

刪除、撤銷、回退

刪除

刪除文件

假設我們有個文件,已經commit到repo中了,需要刪除。
爲此,我們新建一個文本文件delete.txt來模擬這個文件,把它提交到repo中。

這時候我們可以用兩種方法來刪除delete.txt。

1、使用git rm delete.txt

執行這句之後,會輸出一句rm 'delete.txt',這時候到工作區查看,會發現delete.txt已經不在工作區了。

輸入git status,發現輸出如下信息:

On branch feature
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        deleted:    delete.txt

暫存區已經記錄了刪除delete.txt的操作,接下來只要git commit就可以把delete.txt從repo中刪除了。

2、直接從工作區目錄中刪除delete.txt,然後git addgit commit提交修改。

刪除分支

git branch -d <name>可以刪除分支。

例如我們可以刪除之前用來修bug的issue-101分支

git branch -d issue-101

執行後輸出的信息:

Deleted branch issue-101 (was 5d97433).

git branch查看分支,輸出信息中表示只剩master分支跟feature分支了。

如果要刪除一個未合併的分支,默認git會報錯,例如我們創建一個delete分支,在hello.txt中添加一行內容delete branch,然後進行一個commit

git checkout -b delete
git add hello.txt
git commit -m 'update delete branch'

然後切回master分支,刪除delete分支

git checkout master
git branch -d delete

輸出了一個error:

error: The branch 'delete' is not fully merged.
If you are sure you want to delete it, run 'git branch -D delete'.

git告訴你這個分支沒被合併,如果確定要刪除,使用git branch -D delete

執行git branch -D delete,成功刪除。

這個操作通常用來刪除做到一半後面計劃不做了的功能分支。

撤銷

場景:從工作區撤銷

你在hello.txt中寫下了新的一行:I prefer svn
這時候你還沒執行git add
輸入git status,會發現有個提示,(use "git checkout -- <file>..." to discard changes in working directory)

於是按照提示,執行git checkout -- hello.txt
再回去hello.txt看看,新增的那句話已經被撤銷了。

實際上,git checkout所做的,就是把工作區的修改替換成暫存區的。


場景:從暫存區撤銷到工作區

你在hello.txt中寫下了新的一行:I prefer svn
執行了git add hello.txt,把修改添加到暫存區
這時候git會提示你,(use "git reset HEAD <file>..." to unstage)

說得很清楚了,於是我們執行git reset HEAD hello.txt

再執行git status查看,發現修改又回到了工作區。


場景:從repo中撤銷

……,,,遇到這種情況,看接下來的 回退 吧

回退

概念:git中有個HEAD指針,指向當前分支的當前版本,當我們進行回退操作時,其實就是改變HEAD指針,使其指向不同的commit節點。

理解了這個概念,就知道,既然是移動HEAD指針,那我們就可以在任意commit節點間進行跳轉,無論是之前的版本,還是回退到之前版本後,想要回到未來的版本,只要知道commit的id就可以跳轉版本。

使用git reset HEAD --hard <commit_id>來回退。

類似10fb7e42c63586db6948f7a9221bafb32f19409d這樣的就是一個commit id,也可以輸入前面幾位,只要跟其他id有區別就行,如10fb7e4

commit_id可以使用git reflog來查看。(使用git log不能看到回退後未來的commit id)

多人合作

看到這裏,清楚了git的基本操作,包括分支與解決衝突,單人玩git應該可以了,那麼多人合作,其實是類似的,處理好分支與衝突的解決,多人合作也是沒問題的。

遠程repo

github是目前流行的遠程repo之一。具體使用就不細說了。
當對本地repo進行了修改,用git push命令推送到遠程repo就行了,包括分支的改動。

如果別人對遠程的repo進行了修改,或者自己在另一臺電腦上進行之前的項目,用git pull拉取下來就行,這個過程中也可能遇到衝突。

幾個命令

git init 初始化repo

git status 列出未被添加到暫存區與未被提交到repo的修改(經常使用這個命令,對文件的修改以及提交情況會比較清楚)

git add <file> 添加修改到暫存區

git commit -m '<msg>' 提交修改到repo,並附上說明

git push 推送到遠程倉庫

git pull 從遠程倉庫拉取更新,並與本地對應分支合併

git branch 查看本地分支

git branch -a 查看遠程分支

git branch <branch_name> 創建分支

git checkout <branch_name> 切換分支

git checkout -b <branch_name> 新建並切換分支

git merge 合併分支

git stash 保存工作區工作現場

git stash list 查看stash

git stash pop 恢復最後一個stash並刪除stash數據

git stash apply <stash> 恢復指定stash

git stash drop <stash> 刪除指定stash

git rm <file> 將文件從工作區刪除

git branch -d <branch_name> 刪除分支

git branch -D <branch_name> 強制刪除未合併分支

git checkout -- <file> 把修改從工作區撤銷

git reset HEAD <file> 把修改從暫存區撤銷到工作區

git reset HEAD --hard <commit_id> repo版本回退到某個commit

git log 查看commit歷史

git reflog 查看每個操作的log

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章