Previous Article Next Article 架設 GitLab 作 Git 版本控管(七),Git 指令相關 command
Posted in Linux

架設 GitLab 作 Git 版本控管(七),Git 指令相關 command

架設 GitLab 作 Git 版本控管(七),Git 指令相關 command Posted on 2016 年 06 月 04 日Leave a comment

建立使用者資訊

git config --global user.name "cross"
git config --global user.email "cross@ssorc.tw"

查看資訊

git config --global --list

# 或
git config -l

如果遇到因為自建 SSL 的關係,無法 clone

git clone https://git.ssorc.tw:8843/my/code.git
Initialized empty Git repository in /root/test/code/.git/
error: while accessing https://git.ssorc.tw:8843/my/code.git/info/refs
fatal: HTTP request failed
# 或
fatal: unable to access 'https://git.ssorc.tw:8843/my/code.git/': SSL certificate problem: self signed certificate

所以就要關閉 ssl 驗證

git config --global http.sslVerify false

Alias

git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.unstage 'reset HEAD --' # git unstage fileA 等於 git reset HEAD fileA
git config --global alias.last 'log -1 HEAD'   # 查看最新一筆 log
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

vi ~/.gitconfig

[alias]
    co = checkout
    br = branch
    # 利出 local 與 remote branch
    brav = branch -av
    ci = commit
    cim = commit -m
    st = status
    # 漂亮一點的 log, 而 lg -p 可以看到變動的內容
    lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
    # 查看最新一筆 log
    last = log -1 HEAD
    # 查看檔案與 commit 後的不同
    di = diff HEAD^ --
    # push to remote
    pu = push origin
    # pull from remote
    pl = pull origin
    # 連同檔案也秀出
    lgfile = log --name-only
    # 附加到最近一個 commit
    ciamend = commit --amend
    # 刪除最近一個 commit 的
    rehead = reset HEAD^
    # 刪除 local 端的 branch
    rmlobr = branch -d
    # 刪除 remote 端的 branch
    rmrebr = push origin -d

自建 local 端的版本庫

git init

或者複製(clone)一個 remote 版本庫 到 local

就會有一個 code 目錄,裡面有 .git 目錄 (相關 git 就記錄在裡面)

git clone http://git.ssorc.tw:8888/my/code.git

GitLab 對於版本庫有分 private 與 internal 與 public 三種權限,private 是要被授權才可以使用,internal 是註冊使用者都可以用,而 public 是任何人皆可使用

所以以上的 clone 就是 public 的使用方式,

而使用者帳密方式為

git clone https://cross:12345678@git.ssorc.tw:8843/my/code.git

gitlab 還有 token auth key 方式,每個 Project 都會有一組

git clone https://gitlab-ci-token:H8iq5aiScUPdK72TjDhi@git.ssorc.tw:8443/my/code.git

如果 internal 或 private 的版本庫沒有驗證資訊,就會 clone 錯誤

error: The requested URL returned error: 401 Unauthorized while accessing https://git.ssorc.tw:8443/my/code.git/'

也可以透過 ssh 方式

# 先產生 ssh key,滑鼠右鍵,打開 Git Bash Here
ssh-keygen -t rsa -C "cross@ssorc.tw"

# 將 public key 複製起來,貼到 gitlab 裡面 (個人 profile 裡)
cat ~/.ssh/id_rsa.pub | clip

# clone 方式也與 http 連結稍有不同
git clone git@git.ssorc.tw:my/code.git

已存在的版本庫,查看狀態

git status

如果都沒有內容的話,status 會是 initial commit

這時就編寫一個檔案,這個檔案目前 status 是為 untracked ,表示還未納入版本庫裡面

git add 123.txt

此時 status 就成了 stage 了

那如果要取消

git reset HEAD 123.txt

再 commit and comment

git commit -m "add 123.txt"

這樣子動作才算完成提交 commit

也可以,#數字,這是在 gitlab 上會先建立 issue,它會自動產出個數字,然後在 commit 時,可以帶入關連,在gitlab 上的 commit 可以點它導到 issue 裡

git commit -m 'closes #1'
git commit -m 'fixes #1'

commit 事後,想再新增一個檔案進去

git add new-file
git commit --amend
# or
git commit --amend -m 'added new file'

查看記錄 (這個 branch 裡所有 commit 記錄)

git log

# 或,單一檔案的歷史記錄
git log -p file

# 檢視每行程式碼記錄
git blame file

一開始我們是 clone remote 的版本庫,如果 remote 有新的,local 想要更新從 remote,就要用 pull (等於是 fetch + merge)

git pull

# 或
# origin 等於是 remote 名稱的意思
git pull origin master

# 或
git pull origin master:master
git pull origin remotebranch:localbranch
# git pull <REMOTENAME> <REMOTEBRANCHNAME>:<LOCALBRANCHNAME>

把 local 上傳 與 remote master 合併

git push origin master

# 或
git push --set-upstream origin master
# --set-upstream = -u 
# 當一開始是用 git clone 的,之後可以不用下 -u ,這個只是要讓 local 與 remote 建立關連的

上傳其它 local branch to remote

git push origin localbranch

# 但這會讓 remote 變成是 remotes/origin/localbranch

# git push  <REMOTENAME> <BRANCHNAME>

上面的意思就是上傳到 remote origin 下, local 的 localbranch 合併到 remote 的 localbranch

把 local 的上傳 與 remote 合併 成新的 branch (如果要分清楚的話,可以這樣子下)

git push origin master:remotebranch

# master = local branch 名稱
# remotebranch = remote branch 名稱
# 或
git push origin localbranch:remotebranch

# git push  <REMOTENAME> <LOCALBRANCHNAME>:<REMOTEBRANCHNAME> 

# 但小心,git push origin :master 這樣是把 remote 的 master 刪除

git 如何像 svn update 一樣,再次下載檔案

當 remote master 有任何版本更新,local 再 git pull 後,會同步 remote master 下來,
但如果 local 端刪除了某個檔,當再 git pull 時,是不把檔案回復的,
要 git checkout 檔案名稱 (或 git status 知道名稱) ,
才可找回失去的檔案,也可以直接 git checkout . (用點替代)

Windows 環境下,在 commit 時不要自動把 LF 換成 CRLF

git config --global core.autocrlf false

# LF 是 Linux 的 \n
# CRLF 是 Windows 的 \r\n
# 如果在安裝 Git- 時,沒有選擇 checkout as-is,commit as-is 的話,可以下這個指令

可以使用 .gitignore 將要被忽略的檔案,不被 git 追蹤,一個檔一行

 .gitignore

讓中文檔案在 Windows 環境中 git status 時不再顯示亂碼

git config --global core.quotepath false

git 的流程

當我建立一個版本庫時 (管理是 git init 或 git clone),會看到 local 端的有  master 這個名稱,就算它叫 master ,
但仍是一個 branch,一開始開發的版本是跟 master branch 一樣的,clone 它下來後,改完,push 上去,
最好是一個新的 branch,我們就用這個新的 branch 測試,當沒問題後,把 新 branch 合併到 master branch ,
所以 master branch 永遠是最新最正確的一個,之後大家再 pull 它保持最新的狀態持續開發下去,
所以你可能會看到會產生很多個 branch ,這之間會有很多次的分分合合。

git 內鍵有一個指令,可以把它想成是 git log 完整的圖形畫介面

gitk

查看目前的 branch,前面有星號表示正在使用中

git branch

# 或
git branch -r # 遠端的
git branch -a # remote + local

建立新的 branch

git branch localbranch

切換到新的 branch (git bash here 畫面會有提示現在處理那個 branch 底下)

git checkout localbranch

# 或 -b 省去 git branch ,直接建立好就切換過去
git checkout -b localbranch

# 或 從 remote 複製,再切換過去, local branch 不存在
git checkout -b localbranch origin/remotebranch

因為切換到 localbranch,用 git log 看結果是承接 master 的,所以仍看到之前,如果我現在新增檔案在 localbranch 裡,再切換到 master 後,git log 是看不到在  localbranch 裡新增的

假如 local branch 已建立,但 remote branch 不存在,就上傳上去

# 先 git checkout localbranch 切換到 local branch
# 然後
git push --set-upstream origin remotebranch

建立一個 local 不存在,但 remote 存在的 branch,tracking remote branch,以後 pull 或 push 都直接透過 remote 的

git branch --track localbranch2 remotes/origin/remotebranch

# 之後再
git checkout localbranch2

將一個已存在 local 的 branch 直接 tracking remote branch

# 先 checkout
git checkout localbranch3
# 再 --set-upstram-to
git branch --set-upstream-to=origin/remotebranch

# 或
git branch --set-upstream-to=origin/remotebranch localbranch3

# 這個已 deprecated
git branch --set-upstream localbranch3 origin/remotebranch

merge 合併 branch to master

git checkout master
git merge localbranch

刪除 branch

git branch -d localbranch

顯示 remote 版本庫連結

git remote -v

顯示 remote 版本庫細節

git remote show origin

砍掉 commit 重來,刪除最近一個 commit 的

git reset HEAD^

仍是 staged 狀態

git reset HEAD^ --soft

連檔案都刪除

git reset HEAD^ --hard

以上記錄是會不見
假如連回復都要有記錄,git log 就會看到

git revert [commit id]

回到某個 commit 後的狀態,而檔案仍是最新的,用 git status 會看到 modified,可用 git checkout -f 回復,但 git reset HEAD^ 再想 git checkout -f 是回復不了喔

 git reset a8b5a0afea1e1f5faccda4a698c0002bdcc7bf892

不小心 git reset HEAD^ –hard

git reflog
git reset --hard 731f21c

查看遠端 log

git log origin/master

刪除遠端分支 remote branch

git push origin --delete [remotebranch]

查看檔案與 commit 後的不同

git diff HEAD^ -- /path/file
# or
git diff HEAD@{1} /path/file
# or
git log -l -p -- /path/file

遇上 Your branch is ahead of ‘origin/develop’ by 2 commits.,意思是說我 local端的比 remote 端的多了兩個 commit,所以叫我先 git push
所以我可以用這個知道是那兩個

git log origin/develop..HEAD

查看案個 commit 是改了什麼內容

git show <commit_id>

遇到

Please commit your changes or stash them before you switch branches.

因為切到 git branch master 會清掉已修改的內容,但 git 不會讓你這麼做
所以要先暫存

git stash

列出暫存

git stash list

取出暫存

git stash pop

# or 取出某一個
git stash pop stash@{1}

刪除暫存(pop後這個就不需要了)

git stash drop

# or 刪除某一個
git stash drop stash@{0}

不小心把檔案刪除了,我想回復它 (最近 commit 的)

git checkout file

commit 事後,想再新增一個檔案進到以前的 commit (非最近一個)

# git log
commit 29634101cabfb9f9d6017c461a5687f2b88fdc5e
Author: cross <cross@ssorc.tw>
Date: Thu May 11 16:50:08 2017 +0800

fixed 新增需求時的說明

commit 5b6b8d75ae96f2fa8ab721d67dfd93f6a87e11a1
Author: cross <cross@ssorc.tw>
Date: Wed May 10 14:47:08 2017 +0800

added 通知加入

但我後來又修改了當初已 commit 的檔案
所以又

git add new-file old-file
git commit -m 'added 通知加入22'

再看一次 git log 後會變成

# git log
commit 5b6b8d75ae96f2fa8ab721d67dfd93f6a87e11a1
Author: cross <cross@ssorc.tw>
Date: Wed May 10 14:47:08 2017 +0800

added 通知加入22

commit 29634101cabfb9f9d6017c461a5687f2b88fdc5e
Author: cross <cross@ssorc.tw>
Date: Thu May 11 16:50:08 2017 +0800

fixed 新增需求時的說明

commit 5b6b8d75ae96f2fa8ab721d67dfd93f6a87e11a1
Author: cross <cross@ssorc.tw>
Date: Wed May 10 14:47:08 2017 +0800

added 通知加入

也就是要都先 commit 才可以用 rebase
所以我要用 rebase 去弄出最近三筆 commit

git rebase -i HEAD~3

如下 (進入編輯模式)

pick bd73d4d added 通知加入
pick fd19f8e fixed 新增需求時的說明
pick 02849bf added 通知加入22

我要在新加入的那個把 pick 改成 fixup,這樣子就可以合併到前面一個,然後把倒數第二個放到最下面(讓它成為最新一個)

pick bd73d4d added 通知加入
fixup 02849bf added 通知加入22
pick fd19f8e fixed 新增需求時的說明

最後存檔離開(:x)就可以了,會看到 Successfully rebased and updated refs/heads/branch

再 git log 或 git show 的內容就是我要的啦

參考 https://blog.yorkxin.org/2011/07/29/git-rebase
pick = 要這條 commit ,什麼都不改
reword = 要這條 commit ,但要改 commit message
edit = 要這條 commit,但要改 commit 的內容
squash = 要這條 commit,但要跟前面那條合併,並保留這條的 messages
fixup = squash + 只使用前面那條 commit 的 message ,捨棄這條 message

列出 commit 後有那些檔案

git log --name-only

如果只 push 到 remote 我 local 端某個已 commit 的,那串 xxxx 就是 commit sha 值
但很多很久沒 push 了,現在一一 push 是可能發生 (non-fast-forward) 的,我是只好全部再 push 上去 (不會重覆 push )

git push origin xxxxxxxxxxxxxxxxxxxxxxx:develop

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *