2016年6月29日 星期三

project 集中式管理: git 進階圖解

版本控制

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.git

Remote 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



$git push origin (請注意Remote端git權限問題,否則無法push)

...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)


‘matching’ 參數是 Git 1.x 的默認行為,其意是如果你執行 git push 但沒有指定分支,它將 push 所有你本地的分支到遠程倉庫中對應匹配的分支。而 Git 2.x 默認的是 simple,意味著執行 git push 沒有指定分支時,只有當前分支會被 push 到你使用 git pull 獲取的代碼.

設定下面條件後, 再次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


$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添加如下代碼:

                 [receive]
                  denyCurrentBranch = ignore
2. $vi .git/post-receive
             #!/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

要把這個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


$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

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


$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教學









































2016年6月18日 星期六

Ubuntu Dektop GUI 開機 切換成 Console開機


Ubuntu 16.04 boot: Console Mode

步驟1: 備份開機設定檔
$ sudo cp /etc/default/grub /etc/default/grub.orig
步驟2: 編輯/etc/default/grub
$ sudo vi /etc/default/grub

步驟3: 將下列變成註解
#GRUB_CMDLINE_LINUX_DEFAULT=”quiet splash”

步驟4: 將GRUB_CMDLINE_LINUX=""變成
GRUB_CMDLINE_LINUX="text"

步驟5: #GRUB_TERMINAL=console的註解拿掉
GRUB_TERMINAL=console

步驟6: 執行"
$ sudo update‐grub

步驟7: 執行:$ sudo systemctl set-default multi-user.target

重新開機後,就會以文字模式登入!

步驟8: 如果要改回GUI模式開機,執行:
$ sudo systemctl set-default graphical.target
以上!