Sharing

顯示具有 Git 標籤的文章。 顯示所有文章
顯示具有 Git 標籤的文章。 顯示所有文章

2012年10月21日 星期日

Git filter-branch 的使用


最近因為幫忙重新整理 git repository, 所以有機會接觸 git filter-branch, 過去因為 policy 沒有定義好, 所以大家都將 binary 檔也加進 repository, 造成整個 repository 很肥大, 要 checkout 時也必須要等很久, 所以我的任務就是把這些 binary 檔拔掉, 改成用 md5 or sha1 檔案代替, 如果真的需要用到時, 再去另外一個 http server 下載.
http://www.kernel.org/pub/software/scm/git/docs/git-filter-branch.html

假設整個 repository 有 1000 個版本, 那filter-branch 執行的過程, 其實就是依序把這些版本 checkout, 然後執行你指定的指令來改變檔案的內容, 或是甚至新增/刪除檔案, 之後再把修改過的檔案 commit 進去新的 repository. 所以執行完之後, 整個 repository 中每一筆項目的 SHA ID 都會改變, 是個很暴力的作法, 但也因為很暴力, 所以基本上你想要做什麼事應該都可以達成.

Filter

filter-branch 提供了許多不同 filter, 可以幫助你在正確的時間點執行指令

--env-filter

幫助你修改 author name 或是 author e-mail, 可以參考以下網址提供的 script
https://help.github.com/articles/changing-author-info

--tree-filter

幫助你在每一個版本去修改檔案的內容, 新增/刪除檔案, 最常使用的應該也是這個, 以我自己的例子來說, 我會寫一個像以下的 script 把大檔案轉成 sha1 檔
#!/bin/bash
function transform {

    file=$1
    sha1_name=$file.sha1

    if [ -f /tmp/git/$file ]; then
        rm -f $file
        cp /tmp/git/$sha1_name $sha1_name
    else
        sha1sum $file > $sha1_name
        mv $file /tmp/git
        cp $sha1_name /tmp/git
    fi

}

pushd ./bigfile
for file in *.tgz *.zip; do
    if [ ! -f $file ]; then
        continue;
    fi

    transform $file
popd

--index-filter

這個其實是 --tree-filter 的快速版本, 如果你沒有要改變檔案的內容, 只是單純改變 repository 的 history, 那可以使用這個, 因為他不會真的 checkout 檔案, 速度上快很多, 下面兩個網址都有示範, 最常用的功能就是把某一個特定的檔案永久的從 repository 中刪除.
https://help.github.com/articles/remove-sensitive-data
http://dalibornasevic.com/posts/2-permanently-remove-files-and-folders-from-a-git-repository

--msg-filter

這個是用來改變 commit message 的內容, 原來的內容會介由 standard input 輸入, 而你輸出到 standard output 的內容就會作為新的 commit message.
# 舉例來說, 因為 cat 就不會改變內容, 所以 commit message 完全不變
$ git filter-branch --msg-filter cat
# tac 會把內容全部反過來
$ git filter-branch --msg-filter tac

--tag-name-filter

用來改變 tag name, 如果該版本有加上 tag, 那當 checkout 這個版本時, 就會乎叫你指定的指令, 原來的內容會介由 standard input 輸入, 而你輸出到 standard output 的內容就會作為新的 tag name

--subdirectory-filter

把某一個 folder 下的 commit 獨立出來變成一個新的 repository, 如果當你的專案越來越大時, 你可能會想把某個資料夾獨立出來變成一個新專案, 那這個功能就很好用
http://gugod.org/2012/07/split-a-git-repository/

Other Command

--prune-empty

如果有些 filter 產生了空的 commit, 那會主動清除掉

-f --force

強制把暫存區的東西清掉

2012年7月24日 星期二

git 好文分享



Git-rebase 筆記
這篇是我目前為止看到把 rebase 解釋的最清楚的一篇, 之前看了好幾篇, 不論是中文或是英文都無法理解全部的用法, 但這篇配合小例子, 把 rebase 的所有用法都講的很清楚, 所以很推薦
http://blog.yorkxin.org/2011/07/29/git-rebase

Git branching model
這篇主要是在講解一般軟體開發上應該要怎麼維護你的 branch, 其實這樣的觀念不管是 svn/git 都通用, 尤其是長期開發的 project 都應該要這樣管理
http://nvie.com/posts/a-successful-git-branching-model/

Git immersion
帶著你一步步的操作 git, 算是入門篇
中文: http://gitimmersion-apputu.rhcloud.com/
英文: http://gitimmersion.com/

寫給大家的 Git 教學
http://www.slideshare.net/littlebtc/git-5528339

2012年3月13日 星期二

Git 容易忘記的指令


============ 當 Conflict when git pull =====================

http://jackdempsey.me/2010/07/01/git-when-branches-diverge.html

如果 git pull 時發現有 Conflict, 但你又明明沒有加入任何 commit,
有可能是因為原來的 branch 已經走到分支出去了,
你可以打入 git status

wistor@wistor-003:~/KernelBuild/kernel-3.2$ git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 32 and 83 different commit(s) each, respectively.
#
nothing to commit (working directory clean)



第一個數字 32 代表著你比 origin/master 多了 32 個 patch,
第二個數字 83 代表著你比 origin/master 少了 83 個 patch
如果你很有興趣知道是那一些可以利用 git cherry origin/master 來看

接下來你有幾個方式

1. 像網頁上的方式, 執行 git reset --hard HEAD^ 一直到你可以做 fast-forwarded
這個時候再來執行 git pull

wistor@wistor-003:~/KernelBuild/kernel-3.2$ git status
# On branch master
# Your branch is behind 'origin/master' by 83 commits, and can be fast-forwarded.
#

2. 直接執行 git pull --rebase origin/master

3. 如果你有用 smartgit, 可以打開 log tree, 直接選擇你要的點, 然後按下 reset


常用指令說明
http://blog.longwin.com.tw/2009/05/git-learn-initial-command-2009/