Git 初學筆記 - 實作測試

Git 指令操作可見: Git 初學筆記 - 指令操作

此篇主要是把實作測試做個紀錄, 進階操作等有使用時再另外記錄.

Git 建立 Local Repository

  1. $ mkdir project; cd project
  2. $ git init
  3. $ echo "hello" > hello.txt
  4. $ git add .
  5. $ git commit -m 'initial'

Git clone 資料, 資料修改後上傳

  1. $ git clone http://git.example.com/project.git
  2. $ cd project
  3. $ touch new_file.txt
  4. $ git add .
  5. $ git commit -m 'add new_file.txt'
  6. $ git push origin master
  7. $ git pull # 拉看看有沒有更新

Git clone 資料, 資料修改後上傳.(分兩個目錄測試)

  1. $ mkdir /tmp/a /tmp/b
  2. $ cd /tmp/a
  3. $ git clone http://example.com/project_name.git
  4. $ cd /tmp/b
  5. $ git clone http://example.com/project_name.git
  6. $ echo "hello" > hello.html
  7. $ git add hello.html
  8. $ git commit -m 'add hello.html' # local commit.
  9. $ git push # 推到 Server 上.
  10. $ cd /tmp/a
  11. $ git pull # 會看到 hello.html

Local Repository

建立 Local Repository 測試
  1. $ mkdir test; cd test
  2. $ git init
建立新的 branch (new-branch), 並於 branch 去新增檔案
  1. $ git branch new-branch # master
  2. $ git branch # master
    * master
    new-branch
  3. $ git checkout new-branch # 切換到新的 branch
  4. $ git branch # new-branch
    master
    * new-branch
測試 Git staging area (git add . 之後的修改, 不會被 commit 進去)
  1. $ touch new-branch_file.txt # new-branch
  2. $ git add . # new-branch
  3. $ echo "contents." > new-branch_file.txt # new-branch
  4. $ git commit # new-branch, commit 的 new-branch_file.txt 會是空的, 因為修改是在 git add . 之後.
修改過的資料, 不要 commit, 想直接切換到 master(使用 Git stash 將修改紀錄暫存, 將目前 new-branch 的資料 merge 到 mastermaster)
  1. $ git status # new-branch, 會顯示 new-branch_file.txt 有修改, 尚未 commit.
  2. $ git checkout master # new-branch, 切換回 master, 會出現錯誤: "You have local changes"
  3. $ git stash # new-branch, 先把修改的先暫存下來, 先不 commit, 之後取出可用 git stash pop 或 git stash apply
  4. $ git status # new-branch, 會顯示 nothing to commit (暫時先不丟進 commit 裡面)
  5. $ git checkout master # master
  6. $ git merge new-branch # master, 會將 new-branch_file.txt 的空檔案合併進來.
Git 於 master 將檔案砍掉, branch 是否還能存取此檔案.
  1. $ ls # master, master_file.txt, new-branch_file.txt
  2. $ rm new-branch_file.txt # master, 刪掉此檔案
  3. $ git checkout new-branch # master, 切換到 new-branch, 會出現錯誤: "pathspec 'branch' did not match any file(s) known to git."
  4. $ git stash # 先把修改的部份存起來 (砍掉 new-branch_file.txt)
  5. $ ls # master, 此時 new-branch_file.txt 出現了. (因為尚未 commit, stash 的動作並未做寫入)
  6. $ git stash pop # master, 回復剛剛砍掉的狀態, new-branch_file.txt 就消失了.
  7. $ git commit -m 'delete new-branch_file.txt in master' -a # 先砍掉.
切換到 Branch, 去跟 master 做 Merge
  1. $ git checkout new-branch
  2. $ git stash pop # new-branch
  3. $ git merge master # new-branch, 錯誤: "Entry 'new-branch_file.txt' not uptodate. Cannot merge.", 因為檔案有修改.
  4. $ git diff master # 與 master 做 diff, 發現 /dev/null vs file, 所以要把此檔案砍掉.
  5. $ rm new-branch_file.txt
  6. $ git merge master # new-branch, 合併完成
  7. $ ls # new-branch, 只剩 master_file.txt 這個檔案
由 branch(new-branch) 環境 和 Master 分別建立 新的 branch (from-branch, from-master), 並測試未 commit 資料狀況, 新 branch 的狀態.
  1. $ touch new-branch_file.txt # new-branch, 測試未 commit 資料狀況, 新 branch 的狀態.
  2. $ git branch from-branch new-branch # new-branch, 會將 new-branch 目前所有狀態和資料都複製過去
  3. $ git checkout from-branch # from-branch
  4. $ git status # from-branch, 會看到 new-branch_file.txt, 且這個檔案尚未 commit.
  5. $ git branch from-master master # from-branch, 依照 master 開 from-master 的 branch
  6. $ git branch # from-branch
    from-branch
    from-master
    master
    * new-branch
  7. $ git branch -d from-master # from-branch, 砍掉 from-master 的 branch
  8. $ git checkout -b from-master master # from-branch, 建立 from-master 的 branch, 並同時切換過去.
  9. $ git branch # from-master
    from-branch
    * from-master
    master
    new-branch
測試由 Repository 還原檔案內容
  1. $ echo "test" > master_file.txt
  2. $ git checkout master_file.txt # 還原回空檔案 (Repository 的版本是 空檔案)
git pull 出現 error: Entry 'filename' not uptodate. Cannot merge. 解法
  1. git stash # 目前目錄有修改的資料, 先丟進暫存區
  2. git pull # 合併拉下來的修改
  3. git stash pop # 將修改的暫存區資料取出
  4. 去看 unmerge 的部份, 修改完成 commit + push 即可.

Remote Repository 測試

建立 local 端 master
  1. $ mkdir /tmp/a /tmp/b
  2. $ cd /tmp/a
  3. $ git clone http://git.example.com/project.git
  4. $ cd project/
  5. $ touch master-file
  6. $ git add .
  7. $ git commit -m 'add master-file'
  8. $ git push origin master
  9. $ git pull
  10. $ cd /tmp/b # 由此處來建立 branch
  11. $ git clone http://git.example.com/project.git
建立 Remote Repository 的 branch
  1. $ git pull
  2. $ git push origin origin:refs/heads/reps-branch
  3. $ git fetch origin # 更新到最新版本(origin 是 Repository 的版本)
  4. $ git branch -r
  5. $ git checkout --track -b reps-branch origin/reps-branch # 抓取 reps-branch, 並將此 branch 建立於 local 的 reps-branch
  6. $ git pull
  7. $ git branch
    * reps-branch
    master

測試

A 操作, 新增一個檔案, commit 進入 reps-branch, 於 reps-branch commit
  1. $ cd /tmp/a/project
  2. $ git pull
  3. $ git push origin origin:refs/heads/reps-branch
  4. $ git fetch origin
  5. $ git branch -r
  6. $ git checkout --track -b reps-branch origin/reps-branch # 抓取 reps-branch, 並將此 branch 建立於 local 的 reps-branch
  7. $ git pull
  8. $ git branch
    * reps-branch
    master
  9. $ touch reps-branch.txt
  10. $ git add reps-branch.txt
  11. $ git commit -m 'add reps-branch.txt'
  12. $ git push
  13. $ git pull
B 抓取 reps-branch, 並修改資料, 再抓取 reps 的 branch
  1. $ cd /tmp/b/project
  2. $ git clone http://git.example.com/project.git
  3. $ cd project
  4. $ git fetch origin
  5. $ git pull
  6. $ git checkout --track -b reps-branch origin/reps-branch # 丟到 reps-branch 去
  7. $ vim reps-branch.txt # 隨便加些內容
  8. $ git add reps-branch.txt
  9. $ git commit -m 'add some content'
  10. $ git push
  11. $ git pull
A 操作, 更新, 會抓到 B commit 的資料(於 reps-branch)
  1. $ cd /tmp/a/project
  2. $ git pull # 更新 reps-branch.txt 內的資料(B commit 的)

相關網頁


關於 Tsung

對新奇的事物都很有興趣, 喜歡簡單的東西, 過簡單的生活.
本篇發表於 My_Note-Unix。將永久鏈結加入書籤。

Git 初學筆記 - 實作測試 有 23 則回應

  1. Jimmy 說道:

    Tsung, Thanks for your material, It's helpful to learn git.

    Best Regards,
    ...Jimmy

  2. rongsent 說道:

    拜讀你的文章,實在受益良多,但有個問題想請教一下,
    我們公司的SVN Server是在Linux上,專案有.Net及Java,
    目前是透用SVN+commit monitor+email+批次檔自動程式更新(測試機)及通知功能,明年度想要轉換成GIT+Trac方式,目前GIT功能試得差不多了,目前看來是可以發mail及移植舊的SVN專案是ok的,但自動佈署? 不知道有沒有好的解法?

  3. Tsung 說道:

    自動佈署? 是指用 svn release? 還是?

  4. rongsent 說道:

    SVN在Windows平台上有個工具Commit Monitor,它可以監控SVN Commit並去執行特定命令,我是利用這個機制,發email及更新我們的Web網站(.Net/Tomcat),達到自動佈署的目的,但Git好像沒發現這樣的工具,所以才請教您有沒有其它的方法?

  5. Tsung 說道:

    喔喔, 那個並不是 Monitor, 而是 hooks.
    svn 用得應該是 post-commit, git 一樣也有, 也是在 hooks 裡面, 去修改 post-commit 就可以了. 🙂

  6. 47 說道:

    Tsung兄
    我之前有在你的SVN基本指令教學那篇上留言問:
    "請問您一下, 假設我有兩個修訂版1和2, 我在修訂版2裡執行[update to revision]回修訂版1, 接著回到修訂版1後, 進行修改, 再commit時, 就會發生錯誤"
    所以想問你, 換做git, 你的做法是怎樣呢?
    再次麻煩了
    謝謝

    • Tsung 說道:

      git 的作法就有很多種了.
      1.
      git co adebe5e5 # 直接將現在切成舊版, 再把檔案 cp 出來
      git co HEAD # 切回來現在版本, 再把檔案 cp 回去.
      2.
      git co adebe5e5 -b oldversion # 將舊版直接另開 branch, 當然就可以 cp 或任何事.
      git diff master # 還可以直接做比較
      git co master; git branch -D oldversion # 切回 master 並砍掉舊版 branch

  7. 47 說道:

    Tsung兄
    我剛利用你的方法一去測試,
    假設我有4個修訂版,
    修訂版4為最新,
    而我使用
    >git co 修訂版2
    跳到修訂版2後,
    將檔案複製出來,
    再使用
    >git co HEAD
    系統卻說目前的最新版即為修訂版2,
    這樣子好像跳不回修訂版4了?
    看來又是我不知道哪裡懂不清楚了,
    再麻煩指教一下了
    謝謝

    • Tsung 說道:

      HEAD 是回到最近一次 Commit 的版本.
      不然, 另一種就是 git log 看最後一次版本編號, "git co 最後一次的版本編號" 也可以. 🙂

  8. 47 說道:

    有個疑問
    當我git co到指定版本編號後,
    在執行git log時, 會發現最後一個commit版本就是它本身,
    那這樣有辦法再回到原來的最後一版嗎?

    我在想說, 是不是要先再另一個地方(只不同目錄)先clone一份, 然後再執行git co, 再將需要的資料手動cp到原來的地方?
    以上有誤再麻煩指導一下

    謝謝

  9. 47 說道:

    請問一下, 那您說明的那些動作需要在另一個地方(只clone另一份, 在不同目錄)做嗎
    因為如果是在同一份裡做以上動作的話,
    執行
    >git co 版號2
    後, 再執行
    >git co HEAD
    他還是會在版號2, 因為在執行"git co 版號2"後, 查看git log時, 版號2就好像變成是HEAD了

    再麻煩了, 不好意思一直問
    謝謝

  10. russell 說道:

    google 的git如何使用,第一次都联系不成功

  11. Owen 說道:

    請問 git mv 或者直接用 shell 的 mv 指令改了檔案名稱之後,有什麼辦法可以保留該檔案的 history 嗎?

    http://stackoverflow.com/questions/2314652/is-it-possible-to-move-rename-files-in-git-and-maintain-their-history

    我試過上面那篇的 git log --follow ./path/to/file ,但是依然找不到紀錄阿!= =+

    • Tsung 說道:

      mkdir a
      cd a
      git init
      touch apple
      git add apple; git commit -m 'init'
      git mv apple def
      git ci -m 'mv'
      git log --follow def
      有看到 'mv', 'init' 相關記錄有存在耶.

    • owen 說道:

      哦!commit 之後,就跟預期的一樣了!
      [default eea9f03] mv
      1 files changed, 0 insertions(+), 0 deletions(-)
      apple => def (100%)

      謝啦!

  12. owen 說道:

    git push --receive-pack='git receive-pack --reviewer=xxx@yeah.net' origin HEAD:refs/for/master

    用這樣的方式 push 到 gerrit ,gerrit 不會寄信給 reviewer

    但是在 UI 上面直接點選 reviewer ,則 gerrit 會寄信

    格主你怎麼看?

    我發現九個月前 google 討論區有人回報同樣問題(我上面指令是從這討論區貼過來的)

    http://code.google.com/p/gerrit/issues/detail?id=1132

    但是還沒有得到回應就是...

    • Tsung 說道:

      這個指令我沒有用過耶.
      但是既然 UI 點選會寄信, 那是不是直接追看看 UI 送得指令是什麼, 找到那個指令就可以寄信了?

  13. colon 說道:

    我剛學git,請問我在本機上clone了server上的git
    然後在本機上執行
    echo a>a
    git add a;git commit -m 'add a'
    git push
    然後到server上看log 有add a
    但是目錄上看不到 a 這個檔案,請問我缺了什麼步驟嗎? 我以為push就可以像ftp一樣更新server上的檔案了。
    還有請問下push跟push origin master差別在??

    • Tsung 說道:

      Server 需要 git pull.
      push 和 push origin master 做的事情是一樣的 (在沒有 branch 的狀況下)

    • colon 說道:

      你好,感謝你的回覆~
      按照你說的在server 下git pull 出現了
      fatal: 'origin': unable to chdir or not a git archive
      fatal: The remote end hung up unexpectedly

      請問clone user@server:aaa.git 跟 clone user@server:aaa 差別是??

    • Tsung 說道:

      呃, git pull 出現的訊息, 我忘記是什麼原因了, 可能是網路不通? 或者是連接到的點不對?
      vim .git/config 看看是否正確.

      然後 aaa.git 和 aaa .. 應該是一樣的, 只是我都是下 aaa.git, 沒下過 aaa. 🙂

發表迴響