1. 程式人生 > >git基礎問題

git基礎問題

史記 del bar syn 差距 實的 rect log 例如

1).git add 與gitstage的區別

git stage只是git add的同義詞,所以在使用上沒有區別

i)Git倉庫的三個組成部分:工作區(Working Directory)、暫存區(Stage)、歷史記錄區(History)

ii)工作區:在Git管理的正常目錄都算是工作區,我們平時編輯工作都是在工作區完成。

iii)暫存區:臨時區域。裏面存放將要提交的文件快照。

歷史記錄區:git commit 後的記錄區。

git add 和git stage,其實這兩個命令是同一個意思,是因為要跟 svn add 區分,兩者的功能是完全不一樣的,svn add 是將某個文件加入版本控制,而 git add 則是把某個文件加入暫存區,因為在 git 出來之前大家用 svn 比較多,所以為了避免誤導,git 引入了git stage,然後把 git diff --staged 做為 git diff --cached 的相同命令。基於這個原因,我們建議使用 git stage 以及 git diff –staged.

2). git reset 、git revert和git checkout 有什麽區別

共同點:用來撤銷代碼倉庫中的某些更改

不同點:

i). git reset可以將一個分支的末端指向前一個commit。然後再下次git執行垃圾回收的時候,會把這個commit之後的commit都扔掉;

ii). git reset還支持三種標記。用來標記reset指令的影響範圍;

-mixed:會影響到暫存區和歷史記錄區。也是默認選項

--soft:只影響歷史記錄區

--hard:影響工作區,暫存區和歷史記錄區

因為git reset是直接刪除commit記錄,從而會影響其他開發人員的分支,所以不要在公共分支做這個操作

git checkout 可以將HEAD移到一個新的分支,並更新工作目錄。可能會覆蓋本地的修改,所以執行這個指令之前,你需要stash或者commit暫存區和工作區的更改;

git revert和git reset的目的是一樣的,但是做法不一樣,它會創建新的commit的方式來撤銷commit,這樣能保留之前的 commit 歷史,比較安全。另外,同樣因為可能會覆蓋本地的修改,所以執行這個指令之前,你需要 stash 或者 commit 暫存區和工作區的更改;

3).git fetch和git merge和git pull的區別

git pull: 相當於git fetch 和 git merge,即更新遠程倉庫的代碼到本地倉庫,然後將內容合並到當前分支;

git fetch:相當於是從遠程獲取最新版本到本地,不會自動merge ;

git merge : 將內容合並到當前分支.

4).git 與svn的區別

i).git是分布式的,SVN不是: GIT跟SVN一樣有自己的集中式版本庫或服務器,但GIT更傾向於被使用於分布式模式,也就是每個開發人員從中心版本庫/服務器上chectout代碼後會在自己的機器上克隆一個自己的版本庫;

ii).git把內容按元數據存儲,而SVN是按文件存儲: 所有的資源控制系統都是把文件的元信息隱藏在一個類似.svn,.cvs等的文件夾裏。如果你把.git目錄的體積大小跟.svn比較,你會發現它們差距很大。因為,.git目錄是處於你的機器上的一個克隆版的版本庫,它擁有中心版本庫上所有的東西,例如標簽,分支,版本記錄等;

iii).git分支與SVN分支的不同: 分支在SVN中一點不特別,就是版本庫中的另外的一個目錄。如果你想知道是否合並了一個分支,你需要手工運行像這樣的命令svn propget svn:mergeinfo,來確認代碼是否被合並, 所以,經常會發生有些分支被遺漏的情況; 然而,處理GIT的分支卻是相當的簡單和有趣。你可以從同一個工作目錄下快速的在幾個分支間切換。你很容易發現未被合並的分支,你能簡單而快捷的合並這些文件.

iv).git沒有一個全局的版本號,而SVN有;

v).git內容的完整性要優於SVN: GIT的內容存儲使用的是SHA-1哈希算法。這能確保代碼內容的完整性,確保在遇到磁盤故障和網絡問題時降低對版本庫的破壞.

5).git merge與git rebase的區別

git rebase 和 git merge 一樣都是用於從一個分支獲取並且合並到當前分支,但是他們采取不同的工作方式,以下面的一個工作場景說明其區別:

如圖所示:你在一個feature分支進行新特性的開發,與此同時,master 分支的也有新的提交:

為了將master 上新的提交合並到你的feature分支上,你有兩種選擇:merging or rebase

merge執行:

git checkout feature

git merge master

或者: git merge master feature

此時在feature上git 自動會產生一個新的commit(merge commit):

marge 特點:自動創建一個新的commit
如果合並的時候遇到沖突,僅需要修改後重新commit
優點:記錄了真實的commit情況,包括每個分支的詳情
缺點:因為每次merge會自動產生一個merge commit,所以在使用一些git 的GUI tools,特別是commit比較頻繁時,看到分支很雜亂
rebase執行(本質是尋找公共祖先):

git checkout feature

git rebase master

rebase 特點:會合並之前的commit歷史
優點:得到更簡潔的項目歷史,去掉了merge commit
缺點:如果合並出現代碼問題不容易定位,因為re-write了history

合並時如果出現沖突需要按照如下步驟解決:

i). 修改沖突部分

ii). git add

iii). git rebase –continue

iv). 如果第三步無效可以執行 git rebase –skip

git rebase的問題: 不能再公共分支上執行該命令, 如果你rebase master 到你的feature分支, rebase 將所有master的commit移動到你的feature 的頂端。問題是:其他人還在original master上開發,由於你使用了rebase移動了master,git 會認為你的主分支的歷史與其他人的有分歧,會產生沖突.

總結: 如果你想要一個幹凈的,沒有merge commit的線性歷史樹,那麽你應該選擇git rebase;如果你想保留完整的歷史記錄,並且想要避免重寫commit history的風險,你應該選擇使用git merge.

6).git常用命令

git init :創建git庫

git status :查看當前倉庫的狀態

git diff :查看本次修改與上次修改的內容的區別

git add 文件名 :把現在所要添加的文件放到暫存區中

git commit :把git add到暫存區的內容提交到代碼區中

git clone :從遠程倉庫拷貝代碼到本地

git branch :查看當前的分支名稱

git checkout :切換分支

7).git沖突的解決

沖突的產生: 很多命令都可能出現沖突,但從根本上來講,都是merge 和 patch(應用補丁)時產生沖突。而rebase就是重新設置基準,然後應用補丁的過程,所以也會沖突。

git pull會自動merge,repo sync會自動rebase,所以git pull和repo sync也會產生沖突;

常見沖突: 兩個用戶修改了同一個文件的同一塊區域,git會報告內容沖突(內容沖突);

沖突場景:

準備新的feature1分支,繼續我們的新分支開發:

$ git checkout -b feature1

Switched to a new branch ‘feature1‘

修改readme.txt最後一行,改為:

Creating a new branch is quick AND simple.

在feature1分支上提交:

$ git add readme.txt

$ git commit -m "AND simple"

[feature1 14096d0] AND simple

1 file changed, 1 insertion(+), 1 deletion(-)

切換到master分支:

$ git checkout master

Switched to branch ‘master‘

Your branch is ahead of ‘origin/master‘ by 1 commit.

(use "git push" to publish your local commits)

Git還會自動提示我們當前master分支比遠程的master分支要超前1個提交。在master分支上把readme.txt文件的最後一行改為:

Creating a new branch is quick & simple.

提交:

$ git add readme.txt

$ git commit -m "& simple"

[master 5dc6824] & simple

1 file changed, 1 insertion(+), 1 deletion(-)

現在,master分支和feature1分支各自都分別有新的提交,變成了這樣:

這種情況下,Git無法執行“快速合並”,只能試圖把各自的修改合並起來,但這種合並就可能會有沖突,我們試試看:

$ git merge feature1

Auto-merging readme.txt

CONFLICT (content): Merge conflict in readme.txt

Automatic merge failed; fix conflicts and then commit the result.

果然沖突了!Git告訴我們,readme.txt文件存在沖突,必須手動解決沖突後再提交。git status也可以告訴我們沖突的文件:

$ 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")

我們可以直接查看readme.txt的內容:

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

Git用<<<<<<<,=======,>>>>>>>標記出不同分支的內容,我們修改如下後保存:

Creating a new branch is quick and simple.

再提交:

$ git add readme.txt

$ git commit -m "conflict fixed"

[master cf810e4] conflict fixed

現在,master分支和feature1分支變成了下圖所示:

用帶參數的git log也可以看到分支的合並情況:

$ 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基礎問題