changed 5 years ago
Linked with GitHub

7.3 0505 Git小劇場 part2

Case1. 剛剛做了一次commit,後悔了想拆掉重做

預設情境

tingdeAir:git-branch1 tingtinghsu$ git log --oneline
e12d8ef add database.yml in config folder
85e7e30 add hello
657fce7 add container
abb4f43 update index page
cef6e40 create index page
cc797cd init commit

tingdeAir:git-branch1 tingtinghsu$ ls
config		hello.html	index.html	welcome.html
tingdeAir:git-branch1 tingtinghsu$ touch dog.html
tingdeAir:git-branch1 tingtinghsu$ git add dog.html 
tingdeAir:git-branch1 tingtinghsu$ git commit -m "add dog"
[detached HEAD 3595e26] add dog
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 dog.html

解法

解法一: 絕對位置git reset e12d8ef

tingdeAir:git-branch1 tingtinghsu$ git reset e12d8ef
tingdeAir:git-branch1 tingtinghsu$ git status
HEAD detached at e12d8ef
Untracked files:
  (use "git add <file>..." to include in what will be committed)

	dog.html

解法二: 相對位置 git reset HEAD^

tingdeAir:git-branch1 tingtinghsu$ git reset HEAD^
tingdeAir:git-branch1 tingtinghsu$ git status
HEAD detached at e12d8ef
Untracked files:
  (use "git add <file>..." to include in what will be committed)

	dog.html
    
tingdeAir:git-branch1 tingtinghsu$ git log --oneline
e12d8ef add database.yml in config folder
85e7e30 add hello
657fce7 add container
abb4f43 update index page
cef6e40 create index page
cc797cd init commit

GUI
在想復原的前一顆commit:
-> Reset current branch to this commit
-> Using mode:

Mixed - keep working copy but reset index
(保留檔案)

結論: 使用git reset

Case2. 合併發生衝突了,怎麼辦?

預設情境

member分支想合併payment分支

tingdeAir:git-examples2 tingtinghsu$ cd git-conflict/
tingdeAir:git-conflict tingtinghsu$ ls
config		hello.html	index.html	payment.html	welcome.html

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

解法

解法一: (CL)

  1. git status觀察情況
tingdeAir:git-conflict tingtinghsu$ git status
On branch payment
You have unmerged paths.
  (fix conflicts and run "git commit")

Changes to be committed:

	new file:   member.html

Unmerged paths:
  (use "git add <file>..." to mark resolution)

	both modified:   index.html
  1. 打開VS code看被標註為C的檔案:

<<<<<<<: 原本的檔案 (current change)
>>>>>>>: 預計合併的檔案 (incoming change)

    <div class="container">
<<<<<<< HEAD
      <a href="payment.html">金流系統</a>
=======
      <a href="member.html">會員系統</a>
>>>>>>> member
    </div>
  1. 把標注的符號清掉 接受兩者變更
    <div class="container">
      <a href="payment.html">金流系統</a>
      <a href="member.html">會員系統</a>
    </div>
  1. 回到CL確認狀態git status

index.html 檔案仍在工作目錄

tingdeAir:git-conflict tingtinghsu$ git status
On branch payment
You have unmerged paths.
  (fix conflicts and run "git commit")

Changes to be committed:

	new file:   member.html

Unmerged paths:
  (use "git add <file>..." to mark resolution)

	both modified:   index.html

  1. 再次commit
tingdeAir:git-conflict tingtinghsu$ git add .
tingdeAir:git-conflict tingtinghsu$ git commit -m "merge payment and member"
[payment 9353b45] merge payment and member
tingdeAir:git-conflict tingtinghsu$ git log --oneline

9353b45 merge payment and member
f3d9d77 update index page
9f28e3b add payment page
d818770 update links on index page
76940ed add member sign in page
e12d8ef add database.yml in config folder
85e7e30 add hello
657fce7 add container
abb4f43 update index page
cef6e40 create index page
cc797cd init commit

結論: 修改merge後顯示為conflict的檔案,再add. commit

解法二: (Source Tree)

合併member分支到payment分支
在member上點右鍵 -> merge

提示窗出現conflict!提醒要修改

點選預計合併的灰點
驚嘆號「!」檔案按右鍵: Resolve Conflict
再完成add -> commit的步驟

Case 3. 不小心把還沒合併的分支砍掉了,如何救?

預設情境

tingdeAir:git-branch2 tingtinghsu$ git branch
  cat
  dog
* master

站在master刪除dog
訊息顯示: 還沒合併,是否刪除分支?

tingdeAir:git-branch2 tingtinghsu$ git branch -d dog
error: The branch 'dog' is not fully merged.
If you are sure you want to delete it, run 'git branch -D dog'.

確認刪除分支,用-D大D做參數

tingdeAir:git-branch2 tingtinghsu$ git branch -D dog
Deleted branch dog (was 053fb21).

解法

只要把dog貼紙貼回去,dog分支的commit就會再度有人看管

解法一: (CL)

  1. 列出所有HEAD移動過的軌跡,找到之前commit的index
tingdeAir:git-branch2 tingtinghsu$ git reflog
e12d8ef HEAD@{0}: checkout: moving from dog to master
053fb21 HEAD@{1}: checkout: moving from master to dog
e12d8ef HEAD@{2}: checkout: moving from cat to master

按下q離開

  1. 再貼一次貼紙
tingdeAir:git-branch2 tingtinghsu$ git branch new_dog 053fb21
tingdeAir:git-branch2 tingtinghsu$ git branch
  cat
* master
  new_dog

解法二: (Source Tree)

Sourcetree頁面上方 Branch->New Branch 命名new_dog
specified commit: 053fb21

出現新分支

tingdeAir:git-branch2 tingtinghsu$ git branch
  cat
  master
* new_dog

若要再度刪掉new_dog分支,需切換分支才能刪除

tingdeAir:git-branch2 tingtinghsu$ git checkout master
Switched to branch 'master'
tingdeAir:git-branch2 tingtinghsu$ git branch -D new_dog
Deleted branch new_dog (was 053fb21).
tingdeAir:git-branch2 tingtinghsu$ git branch
  cat
* master

結論: 刪掉分支後,把貼紙貼回去,分支就會再長回來

注意: 若太久沒使用(1,2個月後), git的回收機制會把commit收掉

Case 4. 回到過去的某個commit再做一個新的分支出來

預設情境

tingdeAir:git-branch1 tingtinghsu$ git log --oneline
af8df39 add dog CL
e12d8ef add database.yml in config folder
85e7e30 add hello
657fce7 add container
abb4f43 update index page
cef6e40 create index page
cc797cd init commit

解法:

Sourcetree頁面上方 Branch->New Branch 命名st-branch
specified commit: cef6e40

出現新分支

tingdeAir:git-branch1 tingtinghsu$ git branch
  master
* st-branch

在新分支長新的commit

tingdeAir:git-branch1 tingtinghsu$ git commit -m "abc in st-branch"
[st-branch 122ee9e] abc in st-branch
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 abc.html

Case5. 不小心使用hard模式Reset某個Commit, 如何救回來?

使用情境

檔案全部都不見了,只剩下git init

/*master*/
af8df39 add dog CL
e12d8ef add database.yml in config folder
85e7e30 add hello
657fce7 add container
abb4f43 update index page
cef6e40 create index page
cc797cd init commit

tingdeAir:git-branch1 tingtinghsu$ git reset cc797cd  --hard
HEAD is now at cc797cd init commit

tingdeAir:git-branch1 tingtinghsu$ git log --oneline
cc797cd init commit

解法: 使用git reflog

tingdeAir:git-branch1 tingtinghsu$ git reflog
cc797cd HEAD@{0}: reset: moving to cc797cd
af8df39 HEAD@{1}: reset: moving to af8df39
e12d8ef HEAD@{2}: reset: moving to e12d8ef

按q然後

tingdeAir:git-branch1 tingtinghsu$ git reset e12d8ef --hard
HEAD is now at e12d8ef add database.yml in config folder
tingdeAir:git-branch1 tingtinghsu$ ls
config		hello.html	index.html	welcome.html

Case 6. 某個分支的某些commit做的不錯想收進來,但又不想合併整個分支

預設情境

tingdeAir:git-branch1 tingtinghsu$ cd ../git-branch3
tingdeAir:git-branch3 tingtinghsu$ git status
On branch master

nothing to commit, working directory clean

tingdeAir:git-branch3 tingtinghsu$ git log --oneline
e12d8ef add database.yml in config folder
85e7e30 add hello
657fce7 add container
abb4f43 update index page
cef6e40 create index page
cc797cd init commit

tingdeAir:git-branch3 tingtinghsu$ git branch
  cat
  dog
  fish
* master

切到fish分支

tingdeAir:git-branch3 tingtinghsu$ git checkout fish
Switched to branch 'fish'
tingdeAir:git-branch3 tingtinghsu$ ls
dolphin.html	hello.html	shark.html	whale.html
gold-fish.html	index.html	welcome.html

想在dog分支把fish分支的whale檔案包進來
但是不要shark, dolphin, gold fish檔案

解法: 使用cherrypick

cherrypick單字意思: 挑選對自己有利的

兩個分支都會有whale檔案

tingdeAir:git-branch3 tingtinghsu$ git checkout dog
Already on 'dog'

tingdeAir:git-branch3 tingtinghsu$ ls
config		dog2.html	index.html	whale.html
dog1.html	hello.html	welcome.html

tingdeAir:git-branch3 tingtinghsu$ git checkout fish
Switched to branch 'fish'
tingdeAir:git-branch3 tingtinghsu$ ls
dolphin.html	hello.html	shark.html	whale.html
gold-fish.html	index.html	welcome.html

Select a repo