版本控制
project 集中式管理 - git 進階圖解篇
project 集中式管理
git版本控制管理分3種方式:1.中央式(集中式)管理2. 整合管理3.司令官與副手管理.(參考1)
由於開發專案需求;就使用git來做管理專案,順便把過程經驗記錄下來.本文開始先建立Remote端專案;透過兩位user(user1, user2)對專案的修改與更新來探討git集中式管理.
專案:prj_nvp.git
專案檔案已經加入git管理;放在server(以後git所謂的Remote,就是指server端的專案).
下載git Server的專案至本地(Local)
在Local PC上複製server上專案開始開發:
$ git clone ssh://git@60.251.61.76:9022/opt/git/project/prj_nvp.gitRemote Server 與 Local PC
git clone下載後,預設分支(branch)叫master;而Remote端叫origin/master.當Local端有更新的城市內容要上傳,使用command如下:
$git push origin master
當origin有新的更新想下載,使用command如下:
$git pull origin
<Note ***>
git pull origin相當於做了git fetch origin + git merge origin/master.
我們先探討進行專案更改後的後悔的挽救行為!
[git commit 之前]
1.將files變成staged
$git add .
2.將files從staged改成unstated : git reset HEAD <file> $git reset HEAD *
3.將file改爛後;想取回以前版本的source code: git checkout -- <file> $git checkout -- nvp6124.c
[git commit 之後]
/*砍掉前一個commit, ^代表前一個版本*/
$git reset HEAD^
/*提交後發現漏掉某些檔案,可這樣修改*/
$git commit -m "update xxx"
$git add some_file
$git commit --ament
<Note *>
目前操作都是以目前Local分支(branch)而言,也就是master.
探討push事件:user1 目前版本 5403ef8<--a60a684
...nvp_prj/prj_nvp$git push origin
warning: push.default is unset; its implicit value is changing in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the current behavior after the default changes, 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.
In Git 2.0, Git will default 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)
設定下面條件後, 再次push時warning不見了:
$git config --global push.default matching
$git push origin (出現其他錯誤)
root@rdfw:/home/paddy/workspace/nvp_prj/prj_nvp# git push origin
git@60.251.61.76's password:
Counting objects: 5, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 395 bytes | 0 bytes/s, done.
Total 4 (delta 1), reused 0 (delta 0)
remote: error: insufficient permission for adding an object to repository database ./objects
remote: fatal: failed to write object
error: unpack failed: unpack-objects abnormal exit
To ssh://git@60.251.61.76:9022/opt/git/project/prj_nvp.git
! [remote rejected] master -> master (unpacker error)
error: failed to push some refs to 'ssh://git@60.251.61.76:9022/opt/git/project/prj_nvp.git'
root@rdfw:/home/paddy/workspace/nvp_prj/prj_nvp# git push origin
git@60.251.61.76's password:
Counting objects: 5, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 395 bytes | 0 bytes/s, done.
Total 4 (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 ssh://git@60.251.61.76:9022/opt/git/project/prj_nvp.git
! [remote rejected] master -> master (branch is currently checked out)
這是由於git默認拒絕了push操作,需要進行設置,修改Remote端的.git/config添加如下代碼:
[receive]
denyCurrentBranch = ignore
denyCurrentBranch = ignore
$git push origin (成功啦!)
root@rdfw:/home/paddy/workspace/nvp_prj/prj_nvp# git push origin
git@60.251.61.76's password:
Counting objects: 5, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 395 bytes | 0 bytes/s, done.
Total 4 (delta 1), reused 0 (delta 0)
To ssh://git@60.251.61.76:9022/opt/git/project/prj_nvp.git
5403ef8..a60a684 master -> master
<Note ***>
如果push後看不到commit的檔案;需做兩件事:
1. $vi .git/config添加如下代碼:
2. $vi .git/post-receive
#!/bin/sh
GIT_WORK_TREE=/opt/git/project/prj_nvp.git git checkout -f
如果push後看不到commit的檔案;需做兩件事:
1. $vi .git/config添加如下代碼:
#!/bin/sh
GIT_WORK_TREE=/opt/git/project/prj_nvp.git git checkout -f
探討push事件:user2 目前版本 5403ef8<--506b929
$git push origin (user2沒有執行 git pull origin, 就直接push出錯了)
...prj_nvp# git push origin
git@60.251.61.76's password:
To ssh://git@60.251.61.76:9022/opt/git/project/prj_nvp.git
! [rejected] master -> master (fetch first)
error: failed to push some refs to 'ssh://git@60.251.61.76:9022/opt/git/project/prj_nvp.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
所以先pull將Remote端的更動merge進來
$git push origin (= git fetch origin + git merge origin/master)
$git log (merge後產生新的commit)
...nvp_issue21/prj_nvp$git pull origin
git@60.251.61.76's password:
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (4/4), done.
From ssh://60.251.61.76:9022/opt/git/project/prj_nvp
5403ef8..a60a684 master -> origin/master
Merge made by the 'recursive' strategy.
nvp6124_list.c | 9 +++++++++
ohh.txt | 0
2 files changed, 9 insertions(+)
create mode 100644 nvp6124_list.c
create mode 100644 ohh.txt
root@rdfw:/home/paddy/workspace/nvp_issue21/prj_nvp# git log
commit be2c2028f081466f99343b440db6a1acd16df143
Merge: 506b929 a60a684
Author: super <super@gmail.com>
Date: Tue Jun 28 17:11:54 2016 +0800
Merge branch 'master' of ssh://60.251.61.76:9022/opt/git/project/prj_nvp
commit 506b929f3e7ff1cb6ee63d343bdb478141ca34e4
Author: paddy <paddy.chen@talitor.com.tw>
Date: Tue Jun 28 16:27:05 2016 +0800
add user2_fix
commit a60a684add1a5aedf3a37946e27130b82a42d29d
Author: paddy <paddy.chen@talitor.com.tw>
Date: Tue Jun 28 16:19:25 2016 +0800
update: nvp6124_list.c + ohh.txt
commit 5403ef8db220f97fced2f46100439ae003987548
Author: paddy <paddy.chen@talitor.com.tw>
Date: Tue Jun 28 12:07:06 2016 +0800
Uploading source code
但是如果發現,工作上未做完或是有檔案忘記加入;需要取消上次push的commit,這時候先git log
觀察到先前commit:
commit be2c2028f081466f99343b440db6a1acd16df143
Merge: 506b929 a60a684
Merge: 506b929 a60a684
要把這個commit取消再push一次,此時要進行revert動作:
$git checkout master //切換分支至master
$git revert -m 1 be2c2028f081466f99343b440db6a1acd16df143
...nvp_issue21/prj_nvp$git revert -m 1 be2c2028f081466f99343b440db6a1acd16df143
[master a2464ef] Revert "Merge branch 'master' of ssh://60.251.61.76:9022/opt/git/project/prj_nvp"
2 files changed, 9 deletions(-)
delete mode 100644 nvp6124_list.c
delete mode 100644 ohh.txt
delete mode 100644 ohh.txt
$git log
...nvp_issue21/prj_nvp$ git log
commit a2464efdba2cfc03116dabd1f05250d021f18585
Author: super <super@gmail.com>
Date: Wed Jun 29 09:36:48 2016 +0800
Revert "Merge branch 'master' of ssh://60.251.61.76:9022/opt/git/project/prj_nvp"
This reverts commit be2c2028f081466f99343b440db6a1acd16df143, reversing
changes made to 506b929f3e7ff1cb6ee63d343bdb478141ca34e4.
commit be2c2028f081466f99343b440db6a1acd16df143
Merge: 506b929 a60a684
Author: super <super@gmail.com>
Date: Tue Jun 28 17:11:54 2016 +0800
Merge branch 'master' of ssh://60.251.61.76:9022/opt/git/project/prj_nvp
commit 506b929f3e7ff1cb6ee63d343bdb478141ca34e4
Author: paddy <paddy.chen@talitor.com.tw>
Date: Tue Jun 28 16:27:05 2016 +0800
add user2_fix
Author: paddy <paddy.chen@talitor.com.tw>
Date: Tue Jun 28 16:19:25 2016 +0800
update: nvp6124_list.c + ohh.txt
commit 5403ef8db220f97fced2f46100439ae003987548
Author: paddy <paddy.chen@talitor.com.tw>
Date: Tue Jun 28 12:07:06 2016 +0800
Uploading source code
Uploading source code
$git push origin master //復原成功,push至Remote端.
接下來,繼續完成你的工作!
分支管理branch
創建分支:$git branch issue23
$git checkout -b issue23
顯示分支:
$git branch
切換分支:
$git checkout master
$git checkout issue23
Merge
將分支合併至master:
將分支issue23,issue24合併!
$git checkout master
$git merge issue24 //這種合併將commit往前移稱為fast-forward.
接下來要合併issue23:
$git checkout master
$git merge issue23
<Note***>
檔案遇到衝突;先用git status觀察;然後vi file修正問題,然後git commit.(相當於手動Merge)
rebase (在push之前)
與merge採取不同方式;此法將分支變更到你要合在一起的分支.$git checkout issue23
$git rebase master
再來做一次fast-forward:
$git checkout master
$git merge issue23
去除不再使用的分支:
$git branch -d issue24
$git branch -d issue23
<Note ***>
千萬不要對已經Push的東西做Rebase!
<Command>
$git log --graph --all //圖形
<Reference>
1.Git官網
2.Git教學