iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 9
0
自我挑戰組

Git學習筆記系列 第 9

Git 小劇場 解決衝突

  • 分享至 

  • xImage
  •  

圖形化介面工具

接下來的範例會有較多分支間的關係要解說,會借用圖形化介面工具的分支圖來解說

我自己是使用SourceTree這套圖形化介面工具

因為公司的環境,需要一套在Windows及OS X上都可以使用的圖形化介面工具

因此它目前在Windows及OS X上都可以使用,linux平台則還沒釋出相對應的版本

且免費,所以會拿它來輔助操作git

Windows上的TortoiseGit,也是一套很不錯用的工具

如果你用習慣他們的TortoiseSVN的話,應該會對TortoiseGit滿意

不過它目前只有Windows平台上有,若工作環境都是Windows也推薦使用TortoiseGit

  • 在遠端主機上建立版本庫
git --bare init 

--bare 會讓init後的資料夾內只有版本庫,不會包含工作區,且可以接受push

因為一開始我沒有用--bare去init導致,從clone的brancg要push時會有錯誤提示

​$ git push origin master
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 310 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error: 
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error: 
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
To /Users/morrishsu/Documents/git/webRep
 ! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to '/Users/morrishsu/Documents/git/webRep'

遇到這個錯誤就是要去改遠端版本庫的設定值

進到版本庫那編輯config檔,加上下面的設定值

    [receive]
    denyCurrentBranch = ignore
  • 在各個電腦上clone遠端版本庫到本地工作區內
$ git clone /Users/morrishsu/Documents/git/webRep <directory>

情境

有個遠端的git server : webRep

有兩個開發者momo跟lala分別從webRep clone到本機端的工作區

Imgur


其中lala改了index.html的內容,commit並且push到webRep

這時候lalaRep的線圖會是

Imgur

webRep的線圖會是

Imgur


再來momo也去改了同一支檔案

同樣的commit並打算push

push後會遇到提示訊息如下

$ git push origin master
To /Users/morrishsu/Documents/git/webRep
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to '/Users/morrishsu/Documents/git/webRep'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

這時候遠端的線圖不變

momoRep的線圖如下

Imgur

可以發現在藍色的是momoRep的本地端branch master

紅色的是本地追蹤分支的branch

我們可以發現紅色有一個由lala commit的log

且遠端的「origin/master」,「origin/HEAD」是表示遠端分支的HEAD指標是指向這個commit

可以發現此時momoRep是比遠端分支內的版本還多了2個commit,卻也少了1個commit

Source Tree 顯示 「2 ahead 1 behind」

這時候我們應該要先把遠端的資料pull下來,merge後再push

​$ git pull
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

這時候去編輯index.html,會發現裡面加了些標準的衝突解決標記等你去解決衝突

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>My Page</title>
</head>
<body>
<<<<<<< HEAD
	<h1>momo's page</h1>
	<div>learning git</div>
=======
    <h1>lala edit</h1>
>>>>>>> 5e867958ce77ca82663a33396c211d89d869209d
</body>
</html>

合併好之後存檔,再次commit

​$ git commit -m "merge from webRep"
[master 37f6a88] merge from webRep

merge後之線圖如下

Imgur

可以注意到紅色(本地追蹤分支)的部分併回到藍色(momoRep的本地端branch master)的線了

這時候就可以下push指令了

​$ git push                         
warning: push.default is unset; its implicit value has changed in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the traditional behavior, use:

  git config --global push.default matching

To squelch this message and adopt the new behavior now, use:

  git config --global push.default simple

When push.default is set to 'matching', git will push local branches
to the remote branches that already exist with the same name.

Since Git 2.0, Git defaults to the more conservative 'simple'
behavior, which only pushes the current branch to the corresponding
remote branch that 'git pull' uses to update the current branch.

See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)

Counting objects: 9, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (9/9), 849 bytes | 0 bytes/s, done.
Total 9 (delta 3), reused 0 (delta 0)
To /Users/morrishsu/Documents/git/webRep
   5e86795..37f6a88  master -> master

雖然push成功了,但是前面有一串提示訊息主要是在提醒,git push這個指令在2.0之後預設值從matching改為simple

建議去調整git config內的push.default設定為simple

matching跟simple的差別可以看文件說明

push之後的webRep線圖如下

Imgur

這樣一來我們就解決了衝突(conflicts)完成合併(merge)

總結:

今天用到的指令有:


上一篇
Git 小劇場 git diff
下一篇
git pull 到底?
系列文
Git學習筆記31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言