Hello, Git
使用者設定
設定使用者的信箱和名稱
// 先查看目前設定
$ git config --list
// 設定信箱,名稱
$ git config --global user.name "pengpon"
$ git config --global user.email "xxxx@gmail.com"
直接更改 家目錄底下.gitconfig
也可以!
新建Repository
// 建立新目錄
$ mkdir git-demo
$ cd git-demo
// 初始化, 對這個目錄進行版控
$ git init
D:\IT\practice\git-demo>git init
Initialized empty Git repository in D:/IT/practice/git-demo/.git/
// 目錄下會新增.git這個目錄
圖取自為你自己學git
在Git中分成Working Directory
Staging Area
Repository
三個區塊
- 利用
git add
將檔案放入Staging Area - 利用
git commit
將Staging Area檔案放入Repo
讓Git控管
在專案目錄下新增一index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hellp git</title>
</head>
<body>
</body>
</html>
查看目前專案狀態
$ git status
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
index.html
nothing added to commit but untracked files present (use "git add" to track)
告知目前在master分支上, 還沒有任何commit
有一個檔案index.html為Untracked
-> 尚未被加入版控被追蹤
交付這個檔案給Git, 使用git add
$ git add index.html
$ git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: index.html
此時, index.html變成new file的狀態, 表示這個檔案已被放在Staging Area中
比較
git add .
和git add --all
git add .
會將目前目錄下的所有子目錄, 子子目錄都加到Staging Area
git add --all
是將專案所有異動都加入Staging Area
提交這次異動到 Repo, 使用git commit
$ git commit -m "init commit"
[master (root-commit) 54bad65] init commit
1 file changed, 11 insertions(+)
create mode 100644 index.html
練習方便, 要製造空的commit, 可使用
git commit --allow-empty -m "空的"
檢視紀錄
檢視commit紀錄
$ git log
commit 4a28350f1ec538b833d44feb2efd0133b18128ea (HEAD -> master)
Author: pengpon <pengpon214@gmail.com>
Date: Sun Mar 21 14:06:10 2021 +0800
空的
commit 76d880eae294f30e7fe6f9a8b26454c81fd5c7ca
Author: pengpon <pengpon214@gmail.com>
Date: Sun Mar 21 14:06:08 2021 +0800
空的
commit 196ce5e96fd50a0d6c6881022dde1f5abf3d96a2
Author: pengpon <pengpon214@gmail.com>
Date: Sun Mar 21 14:05:54 2021 +0800
空的
commit 54bad65aa0211a96d55798eca2f9fbd24cfb001e
Author: pengpon <pengpon214@gmail.com>
Date: Sun Mar 21 14:04:03 2021 +0800
init commit
可以查看每一次的commit作者, 什麼時候commit, commit訊息
其他
git log
不同的輸出格式$ git log --oneline 4a28350 (HEAD -> master) 空的 76d880e 空的 196ce5e 空的 54bad65 init commit $ git log --oneline --graph * 4a28350 (HEAD -> master) 空的 * 76d880e 空的 * 196ce5e 空的 * 54bad65 init commit
部分Commit
只想要commit檔案的某一個區塊
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hellp git</title>
</head>
<body>
<h1>我是標題</h1>
<p>123123</p>
<header>我是header</header>
<div>我是內容</div>
<footer>我是footer</footer>
</body>
</html>
index.html增加三行
<header>我是header</header>
<div>我是內容</div>
<footer>我是footer</footer>
使用git add
加上-p
參數, 會跳出詢問, 是否要把hunk區塊加入暫存
y->加入整個檔案
e->編輯要加入的內容
$ git add -p index.html
diff --git a/index.html b/index.html
index 68e0558..ccf8e23 100644
--- a/index.html
+++ b/index.html
@@ -8,5 +8,8 @@
<body>
<h1>我是標題</h1>
<p>123123</p>
+ <header>我是header</header>
+ <div>我是內容</div>
+ <footer>我是footer</footer>
</body>
</html>
\ No newline at end of file
Stage this hunk [y,n,q,a,d,e,?]?
// 選擇e
跳出一編輯器, 顯示
# Manual hunk edit mode -- see bottom for a quick guide.
@@ -8,5 +8,8 @@
<body>
<h1>我是標題</h1>
<p>123123</p>
+ <header>我是header</header>
+ <div>我是內容</div>
+ <footer>我是footer</footer>
</body>
</html>
\ No newline at end of file
# ---
# To remove '-' lines, make them ' ' lines (context).
# To remove '+' lines, delete them.
# Lines starting with # will be removed.
#
# If the patch applies cleanly, the edited hunk will immediately be
# marked for staging.
# If it does not apply cleanly, you will be given an opportunity to
# edit again. If all lines of the hunk are removed, then the edit is
# aborted and the hunk is left unchanged.
留下要加入暫存區的內容, 存檔離開
修改 Commit紀錄
方法:
- 使用
git rebase
git reset
拆掉commit, 再重新commit- 使用
--amend
來修改最後一次commit (只有最後一次)
實作amend-修改最後一次commit
$ git log --oneline // 先檢視目前log
0263340 (HEAD -> master) waaaaaaa
4a28350 空的
76d880e 空的
196ce5e 空的
54bad65 init commit
$ git commit --amend -m "add title"
[master 2e9b57c] add tittle
Date: Sun Mar 21 14:20:20 2021 +0800
1 file changed, 1 insertion(+), 1 deletion(-)
$ git log --oneline
2e9b57c (HEAD -> master) add tittle
4a28350 空的
76d880e 空的
196ce5e 空的
54bad65 init commit
追加異動到最後一次commit中, 也可使用–amend
// 增加檔案style.css, 異動index.html $ git status On branch master 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: index.html Untracked files: (use "git add <file>..." to include in what will be committed) style.css no changes added to commit (use "git add" and/or "git commit -a") $ git add --all $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: index.html new file: style.css // 把檔案或是異動併入最後一次commit $ git commit --amend --no-edit [master f8fe91b] add tittle Date: Sun Mar 21 14:20:20 2021 +0800 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 style.css
實作修改歷史訊息-rebase
$ git log --oneline
4449f50 (HEAD -> master) Merge branch 'feature4'
439adbf (feature4) add text
a130319 feature4 function
5979365 conflict fixed
d0f8be1 (feature2) more function
ae6b919 add line
f8fe91b add tittle
4a28350 (feature1) 空的
76d880e 空的
196ce5e 空的
54bad65 init commit
// 使用rebase整理commit
$ git rebase - 5979365
-i
代表要進入互動模式, 後面接 從哪個commit開始
會跳出編輯器
pick a130319 feature4 function
pick 439adbf add text
# Rebase 5979365..439adbf onto 5979365 (2 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
~
~
~
~
p:保留commit
r:修改commit 訊息
pick a130319 feature4 function
r 439adbf add text
esc+:wq
存檔離開
再跳出另一個編輯器
add text
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date: Sun Mar 21 22:13:40 2021 +0800
#
# interactive rebase in progress; onto 5979365
# Last commands done (2 commands done):
# pick a130319 feature4 function
# reword 439adbf add text
# No commands remaining.
# You are currently editing a commit while rebasing branch 'master' on '5979365'.
#
# Changes to be committed:
# modified: index.html
輸入新的commit 訊息, add text 改成 modify text, 存檔離開
$ git rebase -i 5979365
[detached HEAD e8bf6eb] modify text
Date: Sun Mar 21 22:13:40 2021 +0800
1 file changed, 1 insertion(+)
Successfully rebased and updated refs/heads/master.
$ git log --oneline
e8bf6eb (HEAD -> master) modify text
a130319 feature4 function
5979365 conflict fixed
d0f8be1 (feature2) more function
ae6b919 add line
f8fe91b add tittle
4a28350 (feature1) 空的
76d880e 空的
196ce5e 空的
54bad65 init commit
退回到某一個commit
$ git log --oneline
f8fe91b (HEAD -> master) add tittle
4a28350 空的
76d880e 空的
196ce5e 空的
54bad65 init commit
$ git reset 4a28350
Unstaged changes after reset:
M index.html
// 工作目錄留有f8fe91b這個commit異動的檔案
git rest
有三種模式:
- mixed
- 預設參數
- 將Staging Area檔案丟掉
- 不動Working Directory的檔案
- commit拆出來的檔案留在Working Directory
- soft
- Working Directory和Staging Area都留著
- commit拆出來的檔案留在Staging Area
- hard
- Working Directory和Staging Area都丟
簡言之 commit拆分出來的檔案:
- mixed: 丟回工作目錄
- soft: 丟回暫存
- hard:直接掰掰
HEAD?
指向目前所在的分支, 切換分支時.git/HEAD
內容也會更著改變
// 開新分支 feature1 feature2
$ git branch feature1
$ git branch feature2
// 切到分支feature2
$ git checkout feature2
Switched to branch 'feature2'
M index.html
// 查看.git/HEAD
$ cat .git/HEAD
ref: refs/heads/feature2
// 切至master
$ git checkout master
$ cat .git/HEAD
ref: refs/heads/master
使用分支
// 列出目前專案有哪些分支
$ git branch
feature1
feature2
* master
// 新增分支
$ git branch feature4
// 分支改名 feature4改為feature3
$ git branch -m feature4 feature3
// 刪除分支
$ git branch -d feature3
Deleted branch feature3 (was f8fe91b).
// 切換分支
$ git checkout feature2
分支想像成貼紙, 貼在某個commit上
每一次的commit都是一個物件, 指向某個tree物件
合併分支
情境feature2開發告一段落, 準備併回master
// 切回master
$ git checkout master
// 合併分支
$ git merge feature2
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
提醒: index.html發生衝突
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hellp git</title>
</head>
<body>
<<<<<<< HEAD
<h1>我是標題</h1>
<p>123123</p>
<header>我是header</header>
<div>我是內容</div>
<footer>我是footer</footer>
=======
我是feature2
好多功能
>>>>>>> feature2
</body>
</html>
master和feature2的index.html不一致
Git將有衝突的段落標記出來, 上半部是HEAD (master分支), 下半部是feature2的內容
決定取用誰的,並把標記修掉
留下feature2的內容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hellp git</title>
</head>
<body>
我是feature2
好多功能
</body>
</html>
// 修改完後, 繼續將檔案加入暫存
$ git add index.html
$ git commit -m "confilct fixed"
從master再開一個分支feature4, 修改index.html開發功能
開發完成後, 併回master
$ git checkout master
$ git merge feature4
Updating 5979365..a130319
Fast-forward
index.html | 1 +
1 file changed, 1 insertion(+)
Fast-forward快轉模式, 直接master貼紙指到feature4的commit上, 如下圖
如果需要保留線圖, 使用--no-ff
// 切回feature4 異動index.html內容
$ git checkout feature4
$ git add index.html
$ git commit -m "add text"
// 切至master 合併feature4
$ git checkout master
$ git merge feature4 --no-ff
Merge made by the 'recursive' strategy.
index.html | 1 +
1 file changed, 1 insertion(+)
結果會額外做出一個commit,
Revert?
新功能推上線有問題, 用Revert!
$ git log --oneline
e8bf6eb (HEAD -> master) modify text
a130319 feature4 function
5979365 conflict fixed
d0f8be1 (feature2) more function
ae6b919 add line
f8fe91b add tittle
4a28350 (feature1) 空的
76d880e 空的
196ce5e 空的
54bad65 init commit
打算取消最後的commit (e8bf6eb)
$ git revert HEAD --no-edit
[master 9c8f87b] Revert "modify text"
Date: Sun Mar 21 22:46:42 2021 +0800
1 file changed, 1 deletion(-)
$ git log --oneline
9c8f87b (HEAD -> master) Revert "modify text"
e8bf6eb modify text
a130319 feature4 function
5979365 conflict fixed
d0f8be1 (feature2) more function
ae6b919 add line
f8fe91b add tittle
4a28350 (feature1) 空的
76d880e 空的
196ce5e 空的
54bad65 init commit
Revert會增加一個commit去取消不要的commit
適用在已經推出去的commit!
參考書籍
為你自己學Git