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