git workflow常用命令

世有因果知因求果發表於2015-04-23
  1. git init
  2. git status
  3. git add readme.txt
  4. git add --all         Adds all new or modified files
  5. git commit -m"message"
  6. git add '*.txt'    Add all txt file in the whole project
  7. git remote add originName https://github.com/try-git/try_git.git       :告訴git,新增一個類似於bookmark的資訊,以便後面push分享
  8. git remote rm originName :刪除originName這個remote
  9. git remote -v 列出所有已知的remote列表,remote代表了另外一個repo, 比如下圖,mary和我們的repo之間分別建立了兩個remote: mary,origin(clone時自動新增)
  10. git remote update(或者git fetch)執行該命令後,你的repo和remote repo通訊,獲取相關commit,放到你的orgin/master,origin/xxx的remote tracking branch上。隨後通過git status -uno命令來檢查你的local branch和對應的remote tracking branch是否有commit需要加進來。或者另外一種方法可以簡單check一下是否localbranch需要更新: git remote show origin 這時,它會和remote 聯絡看一下是否up-to-date
    [cabox@ githubtest]$ git remote update                                                                                                                     
    Fetching origin                                                                                                                                                            
    Password:                                                                                                                                                                  
    remote: Counting objects: 17, done.                                                                                                                                        
    remote: Compressing objects: 100% (10/10), done.                                                                                                                           
    remote: Total 17 (delta 4), reused 16 (delta 3), pack-reused 0                                                                                                             
    Unpacking objects: 100% (17/17), done.                                                                                                                                     
    From https://github.com/cnweibo/githubtest                                                                                                                                 
       0a2f95b..b0c8d59  kidsitbranch -> origin/kidsitbranch                                                                                                                   
       0a2f95b..4784daf  master     -> origin/master                                                                                                                           
    [cabox@box-codeanywhere githubtest]$ git status -uno                                                                                                                       
    # On branch master                                                                                                                                                         
    # Your branch is behind 'origin/master' by 5 commits, and can be fast-forwarded.                                                                                           
    #                                                                                                                                                                          
    nothing to commit (use -u to show untracked files) 
  11. git revert 134535 將通過重新生成一個commit,撤銷134535這個commit的所有改動,注意僅僅是撤銷這一個commit,歷史資訊裡面並不會刪除這個commit,之後的commit是不受影響的哦
  12. git reset --hard, git clean -f : 注意git reset和git clean操作影響的都是working directory,並不會影響commited snapshots。而git reset卻會永久性的undo changes
  13. git reset --hard/git checkout anotherbranch  : reset --hard通過修改本分支所指向的commit來間接修改HEAD指標;而checkout只是修改HEAD,並不會修改分支的指向
  14. git branch -f branch-name new-tip-commit  :在你reset多次後,你將進入detached mode,你希望將你的branch回退到之前的某個commit,則可以使用這條命令,但是注意你還需要 git checkout branch-name
  15. git branch -a 列出所有的branch,這時可能包含以下兩個
    * master                                                                                                                                                                   
      remotes/origin/master     這個branch就代表了其中的一個origin/master
  16. git branch -v :列出所有branch以及在該branch上的最近一個commit
      kidsitbranch 737efba [ahead 3] 3rd change                                                                                                                                
    * master       1030dba [ahead 4] go
  17. git push -u originName master  (-u tells Git to remember the parameters(設定master這個branch的default upstream為originName), so that next time we can simply run git push and Git will know what to do.)。push到remote的repository以便分享給他人(通過pull操作)。 注意:如果有人同步做了更改,那麼這個push將會失敗,必需首先git pull(暗含兩個操作:一是git fetch,二是從origin/master merge到master)隨後再git push。由於這種情況下會在Log中增加merge的歷史,會汙染這個log,所以更好的方法是用rebase來才做
  18. 一鍵push到多個remote的方法: 1.git remote add all git@github.com:akrabat/projectname.git
    2.git remote set-url --add all ssh://example.com/path/to/projectname.git 這樣all 這個remote就有了兩個url可以來push了。該命令通常可以用於不同staging/production/dev環境的一鍵更新。注意:當push到不同的repo時,所有歷史資訊都會保留,但是branch本身只有push過去了,在被push的central repo上才會有該branch!!也就是說本地的branch只有主動push了才能被其他人分享和使用
  19. git push  <REMOTENAME> <LOCALBRANCHNAME>:<REMOTEBRANCHNAME> 可以在Push remote時指示git將本地branch push到remote上的另外一個branch name, 或者直接 '':remotebranchtobedeleted刪除遠端repo中的branch
    git push origin :testbranch  --刪除server上的testbranch
    git push origin master:production  --將本地的master分支push到origin上並且更名為production branch
    git push origin :refs/tags/1.7.0  --刪除origin所標示的遠端repo中的1.7.0這個tag
    
    
  20. git pull originName master             :git pull操作時,會將所有歷史資訊拉下來,但是比如在develop上面的改動雖然歷史資訊可以看到,但是並未pull到origin/develop上,要想使用,必須git checkout develop, git pull才能包含後面的改動
  21. rsync -arv --exclude-from ".gitignore" ./ git@server:/path/repo/xxxx.git       提供了一種同步repo的簡單方法,不用pull/push操作
  22. git diff         show unstaged differences since last commit 比較working copy和staged copy的區別
  23. git diff HEAD README: 比較README檔案的working copy和committed HEAD copy
  24. git diff commit1 commit2 README: 比較README檔案的commit1和commit2的區別
  25. git add octofamily/octodog.txt
  26. git diff --staged         view staged differences: 比較已經staged(index)區和repo裡的最新commit snapshot做比較.和git diff --cached類似
  27. git reset octofamily/octodog.txt  cancel the staged octodog.txt file
  28. git reset HEAD LICENSE     Unstage staged file for LICENSE file
  29. git checkout -- octocat.txt           從index區域獲取octocat.txt覆蓋工作區
  30. git branch clean_up           create one branch to work on, 注意:當在一個branch中修改了檔案,但是你又沒有stage it,然後checkout到另外的branch,那麼這個修改將依然在working copy中,你可以將這個修改comit到新的branch中。注意branch本身存在的原因和意義:a)當向你的專案增加一個功能時需要建立branch隔離和將來整合;如果你不能給出一個特別意義的名字的時候,不要建立branch
  31. git checkout 514fbe7 :注意當前是在master分支時,checkout歷史commit,則出現如下情況:命令本身返回一條訊息說:we are in a detached HEAD state and that the HEAD is now at 514fbe7. HEAD本身標示了當前checkout的snapshot。這意味著紅色圓圈代表了Git的HEAD。HEAD往往存在於tip of a development branch.但是當我們checkout branch的前一個commit時,HEAD移動到了當前branch的中間。我們不能再說我們仍然在當前branch(master)上因為當前branch(tip點)比HEAD包含了更多的snapshot。這由git branch輸出來反映:we are currently on no branch!
  32. 通常情況下HEAD總是refer to a named branch(比如:master),同時master branch又refers to a specific commit(也就是master的tip那個commit)(tag也指向特定的commit),這樣HEAD也就曲線指向了master分支的tip commit。在這種情況下(master分支狀態下),如果提交一個commit,master這個分支就將被更新,指向到新的tip commit,HEAD通過master間接指向這個新的tip commit。但是如果我們checkout tip commit之前的任何commit,則這時HEAD指向這個中間commit,而master仍然指向master的tip commit,HEAD就和master detached了。
  33. 如果git checkout master,則會更新HEAD指標,HEAD等於master,master就等於tip commit,所以HEAD就等於master的tip commit。而一旦對中間的一個commit checkout,則只更新HEAD為中間的commit(detached state), 而在這種情況下的任何commit都不會改變master,而只會改變HEAD。這時如果再切換到master:git checkout master,則上面的所有新改動就將無任何引用了,過一定週期,git的垃圾收集機制就會起作用,定期清除上面detached狀態下的提交。
  34. git branch -m  master test    將master branch重新命名為test branch
  35. git config remote.testing.push refs/heads/test:refs/heads/master  修改相關ref ,效果等於: git remote add testing xxxxx;git push testing test:master
  36. git config有三個級別, System:適合於全部使用者,配置檔案為/etc/gitconfig;Global:適合於單個使用者,配置檔案為~/.gitconfig;Local:適合於單個repo,配置檔案.git/config,具體地:
  37. git config --global user.name "kids learding"
  38. git config --global user.email "kids@123.com"  執行上述兩條命令後,在~/.gitconfig檔案中,就有了“
    [user]                                                                                                                                                                                   
            name = kids learding                                                                                                                                                                  
            email = kids@123.com
  39. git config user.name;列出現在使用的user.name;git config user.email同樣列出email
  40. git config --global color.ui true :使能終端的輸出color
  41. git config --global push.default simple   :這項配置使得git在push時只將current branch push到github上
  42. git config --global pull.rebase true  :自動在pull時執行rebase操作而不是merge(也就是說:執行git fetch, git rebase origin/master,而不是git merge origin/master),這樣的好處是清除沒有太大意義的空merge commit
  43. git config --global rerere.enabled true   Reuse recorded resolution(ReReRe) :record all fixes to merge conflicts;Reuse them automatically when the same conflict happen. Particullay useful when cherry picking to multiple branches or constantly rebasing.
  44. git config --global alias.s "status -s" =>git s=git staus -s 
  45. git config --global alias.lg "log --oneline --decorate --all --graph" =>git lg= git log --oneline --decorate --all --graph
  46. git config --list 列出所有的git配置專案
  47. .gitignore 檔案列出所有不用被git track的檔案或者資料夾
  48. 另外一種情況是如果檔案已經被tracked了,你又不希望再次被修改,那麼你可以通過執行git update-index --assume-unchanged filename命令,使得git在你的這個repo中暫時對這個檔案失憶,對該檔案的修改不做跟蹤。這個功能非常適合於配置檔案的場景。其匹配的其他命令是:
    git update-index --no-assume-unchanged filename  :取消該功能   ;
    git ls-files -v|grep '^h'       :列出所有被暫時取消track的檔案集合 : 注意這種情況下,只對你自己的repo有效,也就是說只在你本地repo有效,其他人clone repo後仍然是track的!!
    cabox@box-codeanywhere:~/workspace/gitfattest$ git update-index --assume-unchanged read.txt                                                                                              
    cabox@box-codeanywhere:~/workspace/gitfattest$ git ls-files -v|grep '^h'                                                                                                                 
    h read.txt                                                                                                                                                                               
    cabox@box-codeanywhere:~/workspace/gitfattest$ vi read.txt                                                                                                                               
    cabox@box-codeanywhere:~/workspace/gitfattest$ git status                                                                                                                                
    On branch master                                                                                                                                                                         
    Your branch is up-to-date with 'origin/master'.                                                                                             
    nothing to commit, working directory clean                                                                                                  
    cabox@box-codeanywhere:~/workspace/gitfattest$ git update-index --no-assume-unchanged read.txt                                             
    cabox@box-codeanywhere:~/workspace/gitfattest$ git status                                                                                   
    On branch master                                                                                                                            
    Your branch is up-to-date with 'origin/master'.                                                                                             
    Changes not staged for commit:                                                                                                              
      (use "git add <file>..." to update what will be committed)                                                                                
      (use "git checkout -- <file>..." to discard changes in working directory)                                                                      modified:   read.txt                                                                                                                   
    no changes added to commit (use "git add" and/or "git commit -a") 

     

  49. 相對於只對每個repo local修改update-index後才能生效Untracked功能的,還有一種方法即是對原生repo修改,被clone後也會生效的方法是
    git rm --cached file :該命令將取消掉對file的track,這種情況下.gitignore中定義的file就將會被GIT徹底忽略。但是存在的問題是:後面被clone的檔案中將徹底消失這個file檔案!
  50. git checkout clean_up     switch to the clean_up branch  :注意,當執行checkout branch命令時,實際上更新的是.git/HEAD檔案,也就是整個git全域性的HEAD,並且指向被checkout的branch指標(也就是最新一個commit),該檔案內容此時設定為refs/heads/clean_up,也就是說git的HEAD是由clean_up這個branch來決定的,而refs/heads/clean_up檔案實際上就是包含一個40字元的最新commit,這時候,git HEAD, clean_up(branch的指標)是一致的。如果git checkout中間的某一個版本的話,由於.git/HEAD檔案內容會被更新為被checkout指定的那個commit,而不是refs/heads/clean_up了,所以和clean_up或者master都不一致了,因此成為detach狀態。 
  51. git stash  :當修改過一些檔案後,但是還沒有認真測試,這時比如有個hotfix需要解決,那麼就可以執行這條命令,將未完成的工作暫存起來,隨後git checkout hotfix在該hotfix branch上解決問題,完後就可以回到stash的狀態重新繼續工作,執行git checkout master, git stash apply則取回先前被暫存的變更集.如果不想用那個放在git堆疊裡面的stash的話,可以使用命令:git stash clear 來清除掉。 http://www.cppblog.com/deercoder/archive/2011/11/13/160007.html 這篇文章解釋的不錯。注意:git stash apply命令預設從stash stack中取出最新的stash應用到當前branch上,但是並不會刪除stash stack的內容
  52. git stash save --patch 上述命令可以互動式地選擇你要stash哪個檔案
  53. git stash save --keep-index :只將unstaged的變更放到stash stack中
  54. git stash=git stash save ;git stash apply=git stash apply stash@{0};git stash drop=git stash drop stash@{0};git stash pop=git stash apply+git stash drop
  55. 預設情況下git stash只會stash已經track的檔案,你如果希望將新建的檔案(即untracked檔案)也被stash起來的話,需要使用git stash -u/git stash --include-untracked命令
  56. git stash list --stat : 列出stash裡面內容的梗概資訊:改了哪個檔案以及具體更改的內容。。
  57. git stash show stash@{0} ; git stash show --patch
  58. git stash save "add some feature which has not been finished":在建立stash時可以增加一個簡要的說明。。
  59. git stash branch newbrachforthestash stash@{0}
  60. git stash clear
  61. Hook into Git’s Internals: HOOK是一個當Git在某一個事件發生時執行的指令碼。比如只要對central-repo.git的master branch上執行完成了push操作,我們就自動部署到生產環境中去。在central-repo.git目錄,開啟hooks目錄將post-update.sample重新命名為post-update,這個post-update就將被git在post完成後自動執行.

    #!/bin/sh
    
    # Output a friendly message
    echo "Publishing master branch!" >&2
    
    # Remove the old `my-website` directory (if necessary)
    rm -rf ../my-website
    
    # Create a new `my-website` directory
    mkdir ../my-website
    
    # Archive the `master` branch   //注意所有git archive 支援的placeholder都在git help log under the --pretty-format section可以看到
    git archive master --format=tar --output=../my-website.tar
    
    # Uncompress the archive into the `my-website` directory
    tar -xf ../my-website.tar -C ../my-website
    
    exit 0
  62. git rm '*.txt' 
  63. 如何更改一個在git版本控制下的檔名?首先將檔案重新命名A->B,隨後,git rm A;(stop tracking A)git add B;(start to tracking B)
  64. git commit -m "Remove all the cats" :注意當commit時,git將同步更改.git/refs/heads/cureentBranch currentBranch為當前branch名稱,比如master,develop等。也就是說branch本身永遠指向該分支的最後一個commitHEAD本身永遠指向你checkout後工作的那個版本,當他們不一致時,就是一種所謂detach狀態。
  65. git checkout master            switching to master branch
  66. git merge clean_up   merge master with clean_up branch modifications。注意:merge本身只對checkout的分支有效。在這裡有一個知識點:    3-way merge:在crazy這個branch上要merge master,由於crazy和master歷史有diverge(分散),所以為了merge這兩個branch,則需要建立一個額外的merge commit作為兩個branch之間的橋樑。而這個新的commit有兩個parent commit。下面的圖中從crazy分支的tip處有兩個箭頭分別指向crazy和master。就像這樣的說法:這個commit從crazy和master兩個分支來的。在merge後,crazy分支就能訪問crazy以及master的歷史。3-way merge本身的命名就來自:Git looks at the three commits to generate the final state of the merge.
  67. git merge feature --squash :在上面的merge中,由於有所謂3-way merge,這個實際上是一個空的commit,會汙染history,一個可行的方法是使用--squash選項,這樣將簡化歷史資訊

  68. git branch --merged  : 展示在你當前branch上已經merge過的所有branch,一般來說這個列表的內容說明已經被涵蓋在當前branch上,這個列表中的branch如無必要就可以刪除了,因為所有工作已經包含
    $ git branch --merged
    iss53  =>說明iss53的fix已經包含,可以刪除該branch了
    * master
    $ git branch --no-merged
    testing =>說明testing branch未合入,需要適當時候合入。如果這時你想刪除,GIT是不允許你這麼做的。如果需要強行刪除,可以執行:
    $git branch -D testing
  69. git branch --no-merged :展示在當前branch上還沒有merge過來的branch。這個列表中的branch你要注意適當時候做好merge以便包含他們的工作
  70. 需要注意的是上面的git branch --merged/no-merged命令只能列出那些通過git merge命令而被merge的命令,而對於git merge --squash好像並不能準確列出來:git log --graph --left-right --cherry-pick --oneline master...featureX :該命令列出在featurX上有哪些commit還沒有合入進來。
    zhenghuz@CV0005366N0 /d/devenv/Code/gitplayground/mary (master)
    $ git log --graph --left-right --cherry-pick --oneline master...fmary
    
    > e1ad8b2 mary added again to test unmerged //這條也是最新還未merge過的
    > e474cbb mary added again //這條是最新還未merge過的 < 56490e2 merge fmary again < 20eb4ac squash fjohn 9/10 line merged to master < bc413ae solve merge conflicts for master and fmary < fd3c3a8 john on fjohn add 7th and 8th line < 30952a7 Merge branch 'fmary'

     上述命令貌似顯示的不是很準確,最好使用下面的一條命令可以一次性列出所有沒有被merge到master或者develop分支的commits:

    $ git rev-list --all --not master --no-merges | xargs -L1 git name-rev | grep -E '[0-9a-f]{40}'
    54119bb150f22d720a781adca2305d85c9de9190 develop
    c8bc641b087a24bfce7c9b3b2adadc9d308955e6 remotes/origin/develop

     

  71. git branch -d clean_up           delete the clean_up branch after finished work on that branch(注意必須在另外一個branch時才能刪除一個branch)
  72. git push                 push all the work we finished to github 
  73. git push origin --delete featureBranchFinished  = git push origin :featureBranchFinished  刪除已經完成的feature branch
  74. git checkout hotfix迅速解決生產環境中報的一個重要問題
  75. git log --stat 包含統計資訊的方式來展示log   
  76. git log --author=cnweibo  列出所有屬於特定使用者的所有commits
  77. git log --oneline --grep="被搜尋的字串"  查詢所有包括“被搜尋的字串”內容的commits 
  78. git log --follow -p filename :查詢一個filename這個檔案的所有更改歷史
    vagrant@homestead:~/Code/kidsit (develop)$ git log --follow bower.json
    commit b494ada331f7ee042e103ab098077d1178ce2ac0
    Author: cnweibo <matiascx@163.com>
    Date:   Tue Jul 28 04:22:34 2015 +0000
    
        add angular-timer component
    
    commit 1b613522447dd16a70bc693dc558eeab511cd725
    Author: 1372921435 <1372921435@qq.com>
    Date:   Sat Jul 18 09:36:20 2015 -0400
    
        intial non lib version

     

  79. git log --oneline:梗概的方式展示log
  80. git log --graph 以圖形的方式展示log
  81. git log --pretty="%h,%cn,%cr"友好的方式來展示log,這些formating有如下形式: %H-Commit Hash, %ad-Author Date, %h:Abbreviated Commit Hash,%ar-Author Date, Relative, %T-Tree Hash,%cn-Committer Name,%t: Abbreviated Tree Hash, %P-Parent Hashes;%p-Abbreviated parent Hashes;%an-author name;%ae-author email,%ce-committer email,%cd-committer date,%cr-commiter date, relative,%s-subject(commit message)
  82. git log --online --graph --all --decorate 以圖形化方式展示所有branch的comit變更歷史,非常好用。但是注意:如果你在做一個feature時,從master上建立了feature分支,程式碼完成後merge到master上,這時,如果你要檢視圖形化branch、merge歷史則能清晰展示
    *   9eb6e93 (HEAD, master) Merge branch 'feature'
    |\
    | * 523e2ac (feature) tres
    | * 6d3cc0f dos
    | * 1bc0b2e uno
    * | d39734b three
    * | 779d37b two
    * | facbcbf one
    |/
    * 58848f4 Initial commit.

    但是如果你delete了那個feature分支,則從此不會再展示這個分支了。

    *   9eb6e93 (HEAD, master) Merge branch 'feature'
    |\
    | * 523e2ac tres
    | * 6d3cc0f dos
    | * 1bc0b2e uno
    * | d39734b three
    * | 779d37b two
    * | facbcbf one
    |/
    * 58848f4 Initial commit.

    原因是在GIT中branch實際上只是一個對最後的commit引用的指標而已,它會隨著這個branch上的一個一個commit而不斷移動。也就是說一旦這個指標被刪除了,那麼就將沒有記憶體儲存這個branch資訊了。那麼如何能夠找到branch歷史呢?有以下幾個建議:要麼不要刪除分支,因為分支本身並沒有什麼壞處,除非分支太多,螢幕都無法看了;要麼在刪除branch之前將那個commit做一下Tag, Tag本身實際上就是一個不能移動的branch,你甚至可以將Tag命名為你將刪除的branch名稱;或者使用GIT系統預設給的merge commit comments,因為在merge時,系統會自動加上是將哪個branch上的commits merge過來的,這樣你就可以檢視到是從哪個branch上來的。

  83. git log -n 1 :展示最近的一個commit
  84. git log old..new    展示所有在new branch上的commit但是又沒有包含在old branch上的commits.我們甚至可以使用這個filtering語法來指示Git只列出在當前分支上的最近的3條commits: git log HEAD~3..HEAD --stat
  85. git log -p  列印出commit對應的變更
    $ git log -p
    commit f67b73e86513d841dd68dd38f4de7327045f620a
    Author: cnweibo <matiascx@163.com>
    Date:   Mon Mar 28 11:21:25 2016 +0800
    
        remove unused tab inactive style
    
    diff --git a/style.less b/style.less
    index 6dd816a..1c42159 100644
    --- a/style.less
    +++ b/style.less
    @@ -609,7 +609,6 @@ input,textarea,select,button{
             &.inactive{
               color: #666666;
               background-color: @component-background;
    -          border-bottom: ;
               box-shadow: 1px 1px 0 #d4d3d3;
             }
           }
    
    commit 3c88937a145f115002340369216145c5b6d4360b
    Author: cnweibo <matiascx@163.com>
    Date:   Sun Mar 27 17:17:27 2016 +0800
    
        test for archive
    
    diff --git a/LAST_COMMIT b/LAST_COMMIT
    index eb0be20..33416cc 100644
    --- a/LAST_COMMIT
    +++ b/LAST_COMMIT
    @@ -1 +1 @@
    -$Format:Last commit: %h by %aN at %cd%n%+w(76,6,9)%B$
    \ No newline at end of file
    +$Format:Last commit: %d : %h by %aN at %cd%n%+w(76,6,9)%B$
    \ No newline at end of file
    
    commit 48f8866f2ff43482f10345aa8b42ffea75c6c81f
    Author: cnweibo <matiascx@163.com>
    Date:   Sun Mar 27 16:57:04 2016 +0800
    
        exclude json file in the archive
    
    diff --git a/.gitattributes b/.gitattributes
    index 79c4bc0..a8e7392 100644
    --- a/.gitattributes
    +++ b/.gitattributes
    @@ -6,6 +6,6 @@ gulp.config.js export-ignore
     style.less export-ignore
     .idea export-ignore
     .git export-ignore
    -.json export-ignore
    +*.json export-ignore
    
     LAST_COMMIT export-subst
    \ No newline at end of file
    
    commit 472e2479de544ba38ecea0fc6a43835bc0e4923e
    Author: cnweibo <matiascx@163.com>
    Date:   Sun Mar 27 16:54:42 2016 +0800
    
        add archive.sh script for deployment
    
    diff --git a/.gitattributes b/.gitattributes
    index 75fbf24..79c4bc0 100644
    --- a/.gitattributes
    +++ b/.gitattributes
    @@ -6,4 +6,6 @@ gulp.config.js export-ignore
     style.less export-ignore
     .idea export-ignore
     .git export-ignore
    +.json export-ignore
    +
     LAST_COMMIT export-subst
    \ No newline at end of file
    diff --git a/archive.sh b/archive.sh
    new file mode 100644
    index 0000000..d4e3bd6
    --- /dev/null
    +++ b/archive.sh

     

  86. git show 和git diff-tree來檢查一個commit所修改過的檔案集概要 
    $ git show --pretty="format:" --name-only bd61ad98
    
    index.html
    javascript/application.js
    javascript/ie6.js
    
    $ git diff-tree --no-commit-id --name-only -r bd61ad98
    index.html
    javascript/application.js
    javascript/ie6.js
  87. git show 359d234 fileToInvestigate.php : 檢視359d234這個commit中的fileToInvestigate.php檔案的修改
    vagrant@homestead:~/Code/kidsit$ git show bea6234 app/Http/Controllers/Admin/AdminUsersController.php
    commit bea6234678079f7d43f3291dedac55e7766cc0f1
    Author: cnweibo <matiascx@163.com>
    Date:   Mon Jul 20 09:40:16 2015 +0000
    
        admin user update user
    
    diff --git a/app/Http/Controllers/Admin/AdminUsersController.php b/app/Http/Controllers/Admin/AdminUsersController.php
    index 4334ad9..2a948aa 100644
    --- a/app/Http/Controllers/Admin/AdminUsersController.php
    +++ b/app/Http/Controllers/Admin/AdminUsersController.php
    @@ -11,7 +11,9 @@ use Kidsit\Role;
     use Kidsit\Permission;
     use Illuminate\Support\Facades\Lang;
     use Illuminate\Support\Facades\View;
    -
    +use Illuminate\Support\Facades\Validator;
    +use Illuminate\Support\Facades\Input;
    +use Illuminate\Support\Facades\Redirect;
     use Datatables;
     class AdminUsersController extends Controller
     {
    @@ -180,7 +182,12 @@ class AdminUsersController extends Controller
         public function postEdit($user)
         {
             // Validate the inputs
    -        $validator = Validator::make(Input::all(), $user->getUpdateRules());
    +        $validator = Validator::make(Input::all(), array(
    +            'username' => 'required|alpha_dash',

     

  88. git blame :這個命令允許你查詢是哪一個commit,哪一個作者修改了一個檔案的某個特定行,這個命令對於分析是誰在哪個commit中引入了一行變更是非常有好處的。
    vagrant@homestead:~/Code/kidsit (develop)$ git blame -w bower.json
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400  1) {
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400  2)   "name": "kidsit-fe",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400  3)   "description": "kidsit front end vendor components",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400  4)   "version": "0.0.1",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400  5)   "license": "MIT",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400  6)   "private": true,
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400  7)   "dependencies": {
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400  8)     "angular": "1.3.x",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400  9)     "angular-route": "1.3.x",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 10)     "angular-loader": "1.3.x",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 11)     "angular-mocks": "~1.3.x",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 12)     "angular-animate": "~1.3.3",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 13)     "jquery": "~2.1.1",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 14)     "jquery-colorbox": "~1.5.14",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 15)     "angular-bootstrap": "~0.12.0",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 16)     "jquery-color": "~2.1.2",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 17)     "bootstrap": "~3.3.1",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 18)     "angular-toastr": "~0.5.1",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 19)     "angular-busy": "~4.1.2",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 20)     "ng-pageslide": "~0.1.8",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 21)     "PACE": "https://github.com/HubSpot/pace.git#~1.0.2",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 22)     "highcharts": "http://code.highcharts.com/highcharts.js",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 23)     "highcharts-ng": "~0.0.7",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 24)     "underscore": "~1.7.0",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 25)     "angular-underscore": "~0.5.0",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 26)     "bootstrap-hover-dropdown": "~2.0.11",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 27)     "angular-filter": "~0.5.2",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 28)     "angular-validate-directive": "~0.1.0",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 29)     "angular-messages": "1.3.3",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 30)     "ui-router": "~0.2.13",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 31)     "html5shiv": "^3.7.2",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 32)     "respondJs": "~1.4.2",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 33)     "jquery-placeholder": "~2.1.0",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 34)     "greensock": "~1.17.0",
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 35)     "code-prettify": "*",
    b494ada3 (cnweibo    2015-07-28 04:22:34 +0000 36)     "bootstrap-wysihtml5": "*",
    b494ada3 (cnweibo    2015-07-28 04:22:34 +0000 37)     "datatables": "~1.10.7",
    b494ada3 (cnweibo    2015-07-28 04:22:34 +0000 38)     "angular-timer": "~1.3.3"
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 39)   }
    ^1b61352 (1372921435 2015-07-18 09:36:20 -0400 40) }

     

  89. git tag -a v1.2 9fceb02 -m "Message here"  該命令將在一個commit上打上tag,比如在上面的例子中由於bracn被刪除,所以為了標示523e2ac這個commit是從featurexxx分支上merge到master後被刪除的,那麼就可以執行一條命令:git tag -a featurexxx 523e2ac -m "建立永久'branch' featureXXX"
  90. git show v1.2  列出v1.2這個tag的詳細資訊
    (master)$ git show v1.2                                                                                                                                                              
    commit 7bddbdc2a1f8d9c23205707e74455d74684e3031                                                                                                                                          
    Merge: c822db1 3f63840                                                                                                                                                                   
    Author: Taylor Otwell <taylorotwell@gmail.com>                                                                                                                                           
    Date:   Tue Mar 24 16:06:56 2015 -0500                                                                                                                                                   
                                                                                                                                                                                             
        Merge pull request #3318 from TheShiftExchange/patch-1                                                                                                                               
                                                                                                                                                                                             
        Update services.php 
  91. git describe --all commitID : 通過給定一個commit,可以列出和這個commit最近的一個tag(該tag一定是這個commit的祖先)
    (master)$ git describe --all e01c173                                                                                                                                                     
    tags/v5.0.0-1-ge01c173
  92. git describe --tags HEAD 則列出離HEAD最近的那個tag資訊
    $ git describe --tags HEAD
    v1.0-1-g3c88937   //注意這裡的意思是離HEAD最近的是前1個commit打了V1.0的tag!!
    
    Administrator@USER-20151001BU MINGW64 ~/devenvironment/Code/fedevbp (master)
    $ git lg
    * 3c88937 (HEAD -> master) test for archive
    * 48f8866 (tag: v1.0) exclude json file in the archive

     

  93. git checkout -b version2 v2.0.0 從一個tag的版本上建立分支(注意:分支和tag都是一個pointer而已)
  94. git commit -a -m "modify readme" 將add to stage和commit change合二為一(add changes from all tracked files: DOES NOT ADD NEW FILE(untracked)!!)
  95. git reset --soft HEAD^將最後的一個commit rollback到staging area,再做修正後,比如增加新的檔案,修改已有檔案,之後再做commit動作
  96. git add todo.txt; git commit --amend -m "forget the todo.txt in last commit, so amend it here" 這個--amend引數在修正剛剛commit的內容,比如新增新的忘掉commit的內容,和前一個commit合在一起形成一次commit,優化歷史資訊是非常有幫助的!
  97. git reset --hard HEAD^;git reset --hard HEAD^^ 撤銷掉最後一個/兩個commit
  98. 當你checkout一個commit或者一個tag時,你將進入所謂的detached HEAD模式。如果這時你在這種模式下新commit程式碼,以後當你checkout一個branch時你將永遠不會在git log中看到你在detached模式下作的commit,而要找回來你就需要使用git reflog機制
  99. git reset .vs. git checkout : git checkout主要是對working directory操作, git reset主要是對index區進行操作。git checkout和git reset都可以傳入commit和file兩種引數
  100. git reflog是一種記錄HEAD的移動和各個branch的references的機制
    cabox@box-codeanywhere:~/workspace/gitfattest$ git reflog                                                                                                                                    
    91fb73d HEAD@{0}: clone: from https://github.com/cnweibo/gitfattest.git  

    git reflog也列出所有你已經remove掉的commit。注意:git reflog對於branch也有記錄

    cabox@box-codeanywhere:~/workspace/kidsit$ git reflog develop                                                                                                                                
    6ea08d0 develop@{0}: branch: Created from refs/remotes/origin/develop 

     

  101. undo undo 如果在上面的git reset --hard HEAD^命令執行後,git將會把head向前移動一個commit,這時如果你希望反悔,即:你又希望取消剛才的reset hard操作,怎麼辦呢?方法是使用git reflog,該命令列出所有的歷史commit,對於已經被“刪除”的commit,只要沒有被git自動垃圾回收機制所刪除(一般在一個月以上才會被git自動清除),那麼都可以用這個方法來恢復。
    $ git reflog
    9fbb460 HEAD@{0}: reset: moving to HEAD^1
    ecfc3dd HEAD@{1}: reset: moving to HEAD^1
    c62a928 HEAD@{2}: commit: add yinbiao/show
    ecfc3dd HEAD@{3}: commit (merge): strange files
    9fbb460 HEAD@{4}: commit: some strange file deleted
    d7ba3b7 HEAD@{5}: commit: migrations added
    6d89fa2 HEAD@{6}: commit: custom.js
    456d2e7 HEAD@{7}: commit: add custom.js in resource
    cd4f2be HEAD@{8}: pull: Fast-forward
    8b72bf8 HEAD@{9}: commit: update gulpfile
    38afa34 HEAD@{10}: pull: Merge made by the 'recursive' strategy.
    4a22d6f HEAD@{11}: commit: add some trace script
    044456b HEAD@{12}: pull: Fast-forward
    4744f4a HEAD@{13}: commit: let contact-us work with cn language
    c5e78bf HEAD@{14}: commit: add contact-us page for test
    4783e3d HEAD@{15}: checkout: moving from master to master
    4783e3d HEAD@{21}: checkout: moving from master to develop
    4783e3d HEAD@{22}: clone: from https://github.com/yyyy/xxxxx.git
    
    zhenghuz@CV0005366N0 /d/devenv/code/xxxx (master)
    $ git reset --hard c62a928
    Checking out files: 100% (2247/2247), done.
    HEAD is now at c62a928 add yinbiao/show
  102. git clone https://github.com/kidsit/gittest.git  gittest-demo :clone動作實際上包含三個工作:下載庫到本地,建立'origin' remote並且指向clone url以便後續push,checkout initial branch(sets up your local master branch to track the remote master branch (or whatever the default branch is called(就是git remote show origin的結果中  HEAD branch: master 那裡顯示的內容,最終本質上是由repo中的refs/remotes/origin/HEAD檔案所決定 )) on the server you cloned from.)  注意github中clone和fork是有區別的,clone產生一個origin remote, 而對於最原始的那個repo,你則只能通過git remote add upstream urloftheinitialrepo來設定引用
  103. git clone -o kidsitRepo https://github.com/kidsit/gittest.git, 則在git clone完成kidsit的gittest.git repo後,建立一個名為kidsitRepo的remote,而不再是預設的origin名稱,這樣有利於管理你的remote!
  104. git fetch origin, git checkout -b serverfix origin/serverfix  = git checkout --track origin/serverfix: 建立一個local tracking branch serverfix,該分支將和origin/serverfix繫結(建立一種直接的關係)。這時,如果你在tracking branch上,即:serverfix分支上,如果你直接執行git pull命令,則git自動從origin的serverfix分支同步commit,並且自動merge到你的local serverfix上

    Tracking branches are local branches that have a direct relationship to a remote
    branch. If you’re on a tracking branch and type git pull, Git automatically
    knows which server to fetch from and branch to merge into.

  105. git banch -vv -a 
    $ git branch -vv
    iss53 7e424c3 [origin/iss53: ahead 2] forgot the brackets
    master 1ae2a45 [origin/master] deploying index fix
    * serverfix f8674d9 [teamone/server-fix-good: ahead 3, behind 1] this should do it
    testing 5ea463a trying something new

    上述命令顯示我們的local branch iss53實際上tracking了origin/iss53,並且本地有2個commit沒有push,local master branch tracking了origin/master分支並且是up-to-date狀態;serverfix分支tracking了teamone/server-fix-good分支,並且本地有了3個commit沒有push,同時server上有1個commit我們沒有fetch;testing是純粹的local branch. 注意:本命令看到的是最近一次fetch後的結果,它本身並不會主動和remote聯絡更新資訊。因此最好的使用方式是: git fetch --all; git branch -vv -a

  106. git branch cat;git checkout cat :另一個開發人員在clone庫後需要做的就是創branch,並且checkout變換到新的branch上工作
  107. git checkout master; git merge cat:在上述branch工作結束時需要merge到主幹上來
  108. git branch -d cat 工作完畢已經merge隨後就刪除該branch
  109. git checkout -b admin 建立一個admin的branch同時checkout開始在admin branch上工作
  110. fast-forward的概念:如果在建立branch後並且開始工作,在merge到master時,master並無改動,那麼這種情況就是fast-forward
  111. remote branch:當你需要其他人在你的branch上工作時,任何可能存續超過1天時間時。git checkout -b shopping_cart;git push origin shopping_cart,這時link the local branch with the remote branch(tracking)。git add cart.rb;git commit -am "add basic shopping cart feature";git push;這將把本地的shopping_cart branch push到remote,其他人就能看到這個branch了
  112. git branch -r : list all remote branches(origin/master, origin/shopping_cart)
  113. git remote show origin    show the remote , 這條命令將展示:
    $ git remote show origin                                                                    
    * remote origin                                                                                                                
      Fetch URL: https://github.com/cnweibo/githubtest.git                                                                         
      Push  URL: https://github.com/cnweibo/githubtest.git                                                                         
      HEAD branch: master                                                                                                          
      Remote branches:                                                                                                             
        kidsitbranch tracked                                                                                                       
        master       tracked                                                                                                       
      Local branch configured for 'git pull':                                                                                      
        master merges with remote master                                                                                           
      Local ref configured for 'git push':                                                                                         
        master pushes to master (local out of date)   

    注意:在上面的輸出資訊中,其中   HEAD branch: master   指示你的remote origin它的預設分支是master,這樣你一旦從那個repo clone過來時,git自動建立一個local master to track that remote repo master branch!!!

  114. git push origin :shopping_cart         Deletes remote branch, git branch -d shopping_cart Must delete local branch manually
  115. git remote prune origin      :clean up deleted remote branches
  116. git tag; list all the tags, git checkout v0.0.1; checkout code at commit
  117. git tag -a v0.0.3 -m"version 0.0.3" : add a new tag
  118. git push --tags (push new tags) :注意git push時並不會自動將tag上傳,所以需要手工指定: git push origin [tagname].
  119. git fetch(將會從remote的repo master更新到local repo的origin/remote這個分支。當teammember建立了一個分支,並且push到remote repo中時,我們如果需要使用這個分支並且track它時,需要首先git fetch,隨後:git branch --track branch-name origin/branch-name,以便將local的branch-name指向origin/branch-name並且track它。可以使用git remote show origin來檢視是否有local branch track這個remote了。該命令和下面的命令可能等效。
    git branch --set-upstream local-branch-name origin/remote-branch-name、
    git checkout --track -b [branch_name] --track origin[or other remote name]/[remote_branch_name] 上面幾個命令都建立了能夠track remote的branch。所謂track是指在local branch上git pull,git就知道從哪個remote上去取並且merge到哪個local branch上,這時你可以通過git remote show命令來顯示詳細資訊);git rebase;這個動作有三個小步驟:(首先move all changes to master which are not in origin/master(別人已經push的改動)to a temprary area,隨後run all origin/master commits on the master branch;最後執行暫存於臨時區域的所有commit)
  120. 如果你希望在你的git log中看到一個線性的歷史軌跡,則可以使用git pull --rebase,並且可以將此作為git的預設行為
    在.git/config中
    [branch "master"]
      remote = origin
      merge = refs/heads/master
      rebase = true
    或者全域性性地:
    ~/.gitconfig
    [branch]  
      autosetuprebase = always

     

  121. 在你有本地變更,工作還沒有做完從而還沒有commit工作的情況下,你又要獲取remote repo的變更作為基線,那麼參照以下流程a)git stash;b)git pull --rebase(這個動作可以通過上面的配置成為標準動作,其本質是 rebase your local commits on top of the newly pulled-down commits).  c)git stash pop

     

  122. git checkout admin;git rebase master;git checkout master;git merge admin==>形成一種所謂fast-forward的場景。下圖中,在rebase之後,feature branch就有了一個新的parent commit,而它和master所指向的commit是相同的。不同於joining the branches with a merge commit, rebase通過在master tip上來完成master整合到feature branch上的工作,這樣的結果是一個線性的歷史記錄便於閱讀。注意,為了在admin branch 進行merge到master時歷史commit不要太過細節,我們可以使用git rebase -i來整合admin branch上的所有commit,使得這些commit可以作為一個整體一次性commit,這樣歷史資訊就很單純了。比如你可能看到的就是admin feature added into master,而不是admin feature的5個細節commit

    rebase local changes
    you’ve made but haven’t shared yet before you push them in order to clean up
    your story, but never rebase anything you’ve pushed somewhere

  123. git rebase -i HEAD~3 :將HEAD的前3個commits重新整合。當你需要在相同的branch上修正一個提交之後的所有提交時(注意該命令將影響你指定的commit之後的所有commit!!),這個命令就派上用場了。rebase -i的原理就是將本branch上的指定commit之後的所有commit臨時放到一個空間中,你可以選擇pick,edit,squash,reword,fixup,隨後將按照你的新的要求來replay這些commits。還有比如你希望將兩個commits的歷史做一下調整顛倒的話,也可以用,這時只需在popup出來的editor中顛倒更改兩個commits的行文順序,後面就會按此順序replay commits了。注意:rebase -i命令展示的commits順序(最舊到最新)和git log --oneline是相反的(最新到最舊)。還有一種需求場景是希望將一個歷史的commit分解為幾個commit
  124. git log --oneline  以一行一個commit的方式展示修改歷史
  125. 假設以下場景:master和unicorns兩個branch,unicorns從master第一個commit後建立的,隨後master和unicorns各有兩個本分支的commit,現在如何在unicorns上同步呢? git checkout unicorns;git rebase master(在unicorns分支上rebase master分支的內容);
  126. git rebase --onto master server client :這個有點複雜,

    Check out the client branch, figure out the patches from
    the common ancestor of the client and server branches, and then replay
    them onto master                           git rebase master server :replay server work on top of master

  127. git-cherry-pick   : Apply the changes introduced by some existing commits
  128. git ls-remote --heads upstream   :僅列出upstream repo中所有的branch
    $ git ls-remote upstream
    4783e3d9a4d7e9c7ea117b4277b859674651dbb4        HEAD
    4783e3d9a4d7e9c7ea117b4277b859674651dbb4        refs/heads/develop
    4783e3d9a4d7e9c7ea117b4277b859674651dbb4        refs/heads/f_migration
    4783e3d9a4d7e9c7ea117b4277b859674651dbb4        refs/heads/master
    98aa6d8c2801c9639db39466f12804285eda6eec        refs/tags/v0.0.1
  129. git fetch --all; git branch -vv -a 這兩個命令組合是檢查repo之間同步情況的最有效方式
  130. git check-ignore -v .  檢視本資料夾是由哪個gitignore rule而導致被忽略掉的

    vagrant@homestead:~/code/kidsit/resources/assets/bower_components$ git check-ignore -v .
    .gitignore:7:resources/assets/bower_components/ .

     

    vagrant@homestead:~/Code/kidsit$ git fetch --all
    Fetching origin
    From https://github.com/cnweibo/kidsit
     * [new branch]      develop    -> origin/develop
     * [new branch]      f_migration -> origin/f_migration
    
    $ git branch -vv -a
    * master                     4783e3d [origin/master] initial runnable version based on laravel5.1
      remotes/origin/HEAD        -> origin/master
      remotes/origin/develop     4783e3d initial runnable version based on laravel5.1
      remotes/origin/f_migration 4783e3d initial runnable version based on laravel5.1
      remotes/origin/master      4783e3d initial runnable version based on laravel5.1
  131. TO BE ADDED
  132. git ls-files  :列出index和working directory中的檔案列表 
    vagrant@homestead:~/code/codeanywhereconsoleenv (master)$ git ls-files
    .bash_profile
    .bashrc
    .gitconfig
    git-aware-prompt/LICENSE
    git-aware-prompt/README.md
    git-aware-prompt/colors.sh
    git-aware-prompt/main.sh
    git-aware-prompt/preview.png
    git-aware-prompt/prompt.sh

     vagrant@homestead:~/code/codeanywhereconsoleenv (master)*$ git ls-files -m :只列出working directory和index不同的檔案(也就是修改過的) -d:列出刪除了的
      .gitconfig

     
    vagrant@homestead:~/code/codeanywhereconsoleenv (master)*$ git ls-files -s  : -s引數將輸出blob的sha
    100644 cbd26e0815ae1f66f6658281e93f1e0be6eb579c 0       .bash_profile
    100644 71d2312c4ec072698a905cf94e8ee480b7bdb589 0       .bashrc
    100644 fab46aec849e85527d018878d878f2cd82ecd439 0       .gitconfig
    100644 3bbbc1ee92562e6a2eebfc6a366f4309d06c7d54 0       git-aware-prompt/LICENSE
    100644 f4f240652a9ec7d698554e0fa81465b885389453 0       git-aware-prompt/README.md
    100644 448ad10727d1a84dd6e2572c033b42f1e775f847 0       git-aware-prompt/colors.sh
    100644 620d7ed172b4dc64226fb60f6d542c63d7429cd5 0       git-aware-prompt/main.sh
    100644 2bafa65cb58464475bcc9861547ad679e1159a71 0       git-aware-prompt/preview.png
    100644 6a737b848df0a8bd52a1eb0a7cb4c67b71e4b258 0       git-aware-prompt/prompt.sh
    vagrant@homestead:~/code/codeanywhereconsoleenv (master)*$ git cat-file blob fab46aec849e85527d018878d878f2cd82ecd439

     

     

  133. git bisect :查詢1.2和1.6之間開始引入bug的版本
  134. 查詢一個檔案在哪個commit中第一次git add的
    vagrant@homestead:~/Code/kidsit (develop)$ git log --diff-filter=A -- public/favicon.ico
    commit 1b613522447dd16a70bc693dc558eeab511cd725
    Author: 1372921435 <1372921435@qq.com>
    Date:   Sat Jul 18 09:36:20 2015 -0400
    
        intial non lib version

     

  135.  git log -- public/favicon.ico 檢視單獨檔案的歷史資訊
    git vagrant@homestead:~/Code/kidsit (develop)$ git log -- public/favicon.ico
    commit 60ba5a064962db5fa05aa0bbe20038c4fef47677
    Author: cnweibo <matiascx@163.com>
    Date:   Fri Jul 31 04:24:57 2015 +0000
    
        admin grade primary work
    
    commit 1b613522447dd16a70bc693dc558eeab511cd725
    Author: 1372921435 <1372921435@qq.com>
    Date:   Sat Jul 18 09:36:20 2015 -0400
    
        intial non lib version

     

  136. git show SHA:file  直接獲取一個檔案特定版本內容
    vagrant@homestead:~/Code/kidsit (develop)$ git show 60ba5a064962db5fa05aa0bbe20038c4fef47677:public/favicon.ico 
    #$# git-fat da39a3ee5e6b4b0d3255bfef95601890afd80709                    0

     

  137. 只checkout一個檔案的特定版本,其他歷史不變: 
    git checkout commitSHA file/to/restore
  138. 一次性列出所有conflict的檔案
    vagrant@homestead:~/Code/kidsit (detached*)*$ git diff --name-only --diff-filter=U
    public/favicon.ico

     

  139. git filter-branch --tree-filter 'rm -f password.txt' -- --all(所有branch)/HEAD(當前branch) :刪除所有branch上的所有commits中所包含password.txt檔案,並且重新commit。重寫歷史!注意這條命令將在所有的branch上checkout所有的commit,並且執行後面'rm -f password.txt'的命令,並且再次commit,如果是很大的repo的話,這個是很耗時的。如果使用--index-filter的話,則不用checkout,而是直接在index/staging area操作,這樣將會大大提高效率。這時上述命令就將調整為:git filter-branch --index-filter 'git rm --cached --ignore-unmatch password.txt' ; 
  140. git filter-branch -f --prune-empty -- --all :刪除所有沒有更改檔案的commits
  141. git checkout --track origin/develop  :建立本地branch以便tracking origin repo的develop分支
$ git checkout --track origin/develop
M       vendor/mockery/mockery/.styleci.yml
M       vendor/monolog/monolog/.php_cs
M       vendor/psy/psysh/.styleci.yml
M       vendor/swiftmailer/swiftmailer/tests/_samples/charsets/iso-2022-jp/one.txt
Branch develop set up to track remote branch develop from origin.
Switched to a new branch 'develop'
vagrant@homestead:~/Code/kidsit$ git checkout -- . 

 

常見問題解決方法:

  • 出現一大片可能不是你希望看到的“modified”,比如:

        modified:   vendor/zizaco/entrust/src/Entrust/Traits/EntrustUserTrait.php
        modified:   vendor/zizaco/entrust/src/commands/MigrationCommand.php
        modified:   vendor/zizaco/entrust/src/config/config.php
        modified:   vendor/zizaco/entrust/src/views/generators/migration.blade.php

no changes added to commit (use "git add" and/or "git commit -a")
vagrant@homestead:~/code/kidsit$ git diff app/Console/Commands/Inspire.php
diff --git a/app/Console/Commands/Inspire.php b/app/Console/Commands/Inspire.php
old mode 100644
new mode 100755

這些奇怪的變動,可能是由Unix檔案許可權模式的變更,老的模式包含+x,新的模式不含這個x,

That looks like unix file permissions modes to me (755=rwxrw_rw_644=rw_r__r__) - the old mode included the +x (executable) flag, the new mode doesn't.

This msysgit issue's replies suggests setting core.filemode to false in order to get rid of the issue:

 解決的方法就是:

git config core.filemode false
  •  git status出現一大片不是你希望看到的“改動”

可能的原因:當你在多個作業系統中協同使用git來工作的時候,由於不同OS對於Enter鍵的處理有不同,所以有可能在你做git status時出現大片由於enter鍵區別導致的改動。解決方法就是:

git config --global core.autocrlf true
  •  偶爾出現明明是你新install的component(比如使用composer require),當你git status時,git卻總是說Nothing to add

這個可能的原因是:要麼該目錄被.gitignore了,你可以使用git check-ignore -v directory來檢查,也可能是由於第三方庫配置了submodule的緣故。比如我在require一個bllim/datatables時,就出現這種怪異現象。

cabox@box-codeanywhere:~/workspace/temp/tmp/vendor$ git check-ignore bllim/datatables/README.md                                                                                                  
fatal: Pathspec 'bllim/datatables/README.md' is in submodule 'bllim/datatables' 

解決辦法: 1,刪除.git目錄(我不需要submodule),2,git rm --cached directory 3. git add directory

這時,再執行git status, git就能發現vendors/bllim/datatables了!

  •  如何一次性刪除所有untracked file??  

    vagrant@homestead:~/Code/kidsit (feature/mathskillcatmanage)*$ git clean -d --dry-run
    Would remove app/Http/Controllers/Admin/AdminMathskillcatController.php
    Would remove public/htmlapp/math/
    Would remove public/htmlapp/system/
    Would remove public/preparebuild/assets/libs/angular-ui-event/
    Would remove public/preparebuild/assets/libs/angular-ui-indeterminate/
    Would remove public/preparebuild/assets/libs/angular-ui-mask/
    Would remove public/preparebuild/assets/libs/angular-ui-scroll/
    Would remove public/preparebuild/assets/libs/angular-ui-scrollpoint/
    Would remove public/preparebuild/assets/libs/angular-ui-uploader/
    Would remove public/preparebuild/assets/libs/angular-ui-utils/
    Would remove public/preparebuild/assets/libs/angular-ui-validate/
    Would remove public/preparebuild/assets/libs/angular-xeditable/
    Would remove resources/views/admin/mathskillcats/
    Would remove resources/views/admin/partials/csrf_token.blade.php
    Would remove resources/views/admin/partials/indicatorcontainer.blade.php

    git clean -d -f
    Removing public/htmlapp/math/
    Removing public/htmlapp/system/
    Removing public/preparebuild/assets/libs/angular-ui-event/
    Removing public/preparebuild/assets/libs/angular-ui-indeterminate/
    Removing public/preparebuild/assets/libs/angular-ui-mask/
    Removing public/preparebuild/assets/libs/angular-ui-scroll/
    Removing public/preparebuild/assets/libs/angular-ui-scrollpoint/
    Removing public/preparebuild/assets/libs/angular-ui-uploader/
    Removing public/preparebuild/assets/libs/angular-ui-utils/
    Removing public/preparebuild/assets/libs/angular-ui-validate/
    Removing public/preparebuild/assets/libs/angular-xeditable/
    Removing resources/views/admin/mathskillcats/

 

如何一次性清除所有的改動?包括unstaged(modified),untracked? 隨後也就將git flow中建立的新feature delete掉?一種可行的方法是:

git stash save --keep-index 和git stash drop
vagrant@homestead:~/Code/kidsit (feature/mathskillcatmanage)*$ git stash save --keep-index 
Saved working directory and index state WIP on feature/mathskillcatmanage: 417f2ec printmath.css
HEAD is now at 417f2ec printmath.css
vagrant@homestead:~/Code/kidsit (feature/mathskillcatmanage)$ git status
On branch feature/mathskillcatmanage
nothing to commit, working directory clean
vagrant@homestead:~/Code/kidsit (feature/mathskillcatmanage)$ git stash list
stash@{0}: WIP on feature/mathskillcatmanage: 417f2ec printmath.css
vagrant@homestead:~/Code/kidsit (feature/mathskillcatmanage)$ git stash drop
Dropped refs/stash@{0} (a5df6ceb236bd864cf182cca3685559a3406ce27)
vagrant@homestead:~/Code/kidsit (feature/mathskillcatmanage)$ git status
On branch feature/mathskillcatmanage
nothing to commit, working directory clean
vagrant@homestead:~/Code/kidsit (feature/mathskillcatmanage)$ git flow feature delete mathskillcatmanage
Switched to branch 'develop'
Deleted branch feature/mathskillcatmanage (was 417f2ec).

Summary of actions:
- Feature branch 'feature/mathskillcatmanage' has been deleted.
- You are now on branch 'develop'
  •  如果你使用git fat來管理你的大檔案時,當clone一個repo後第一件事兒你可能需要git fat init初始化git fat meta資料,隨後你需要執行git fat pull操作,隨後如果你執行git pull --rebase這個動作時,你就可能會因為變更了你的repo中的fat檔案(即便是file mode之類的變更!),所以當執行git pull --rebase時出現unstaged files, can not commit,而同時奇怪的是當你git status時又無任何輸出。這時將會是一團霧水。你可以執行git diff-files來找到git 認為的曾經被變更的檔案集,給你一些解決問題的思路。之所以想到這個主意是因為發現git rebase實際上是/usr/libexec/git-core/git-rebase這個shell指令碼,搜尋"have unstaged changes"發現只有以下地方有列印:
    require_clean_work_tree () {
        git rev-parse --verify HEAD >/dev/null || exit 1
        git update-index -q --ignore-submodules --refresh
        err=0
    
        if ! git diff-files --quiet --ignore-submodules
        then
            echo >&2 "Cannot $1: You have unstaged changes."
            err=1
        fi
    
    [ ... ]

    所以從上面的程式碼就可以看出一定是git diff-files命令有檔案輸出故而才會列印have unstaged changes

    cabox@box-codeanywhere:~/workspace/kidsit$ git pull --rebase                                                                                                                                           
    Cannot pull with rebase: You have unstaged changes.                                                                                                                                                    
    Please commit or stash them.  

    cabox@box-codeanywhere:~/workspace/ktest/kidsit$ git status
    On branch master
    Your branch is up-to-date with 'origin/master'.
    nothing to commit, working directory clean

    abox@box-codeanywhere:~/workspace/kidsit$ git diff-files    
    :100644 100644 565a0e6b45a0fde1ccd1f39ee2bc6b0ba81ac0b0 0000000000000000000000000000000000000000 M      storage/uploaded/yinbiaomp3/1409927256_10.mp3                                                  
    :100644 100644 a08e9d3b68da37f2e233d0d103e2a3a90405ab3e 0000000000000000000000000000000000000000 M      storage/uploaded/yinbiaomp3/1409927276_10.mp3                                                  
    :100644 100644 baad2e2763847dded441f59776b7e9a544f0cea8 0000000000000000000000000000000000000000 M      storage/uploaded/yinbiaomp3/1409927297_5.mp3                                                   
    :100644 100644 a694caba87b3b4d4a57f9070a9d983e368ad8a14 0000000000000000000000000000000000000000 M      storage/uploaded/yinbiaomp3/1409927315_8.mp3   
    
    cabox@box-codeanywhere:~/workspace/kidsit$ git diff  storage/uploaded/yinbiaomp3/1409927276_10.mp3                                                                                                     
    warning: LF will be replaced by CRLF in storage/uploaded/yinbiaomp3/1409927276_10.mp3.                                                                                                                 
    The file will have its original line endings in your working directory.                                                                                                                                
    diff --git a/storage/uploaded/yinbiaomp3/1409927276_10.mp3 b/storage/uploaded/yinbiaomp3/1409927276_10.mp3                                                                                             
    index a08e9d3..373f7b6 100644                                                                                                                                                                          
    --- a/storage/uploaded/yinbiaomp3/1409927276_10.mp3                                                                                                                                                    
    +++ b/storage/uploaded/yinbiaomp3/1409927276_10.mp3                                                                                                                                                    
    @@ -1 +1 @@                                                                                                                                                                                            
    -#$# git-fat c3ea5a9a54d0809b60de406d4951905b9c6625bc                 9040                                                                                                                             
    +#$# git-fat d20e15ce5c6b8ecd2fd2f0d2fd2a498dddfee7d8                   75 
  • 如何實現當git push origin master時,自動觸發deployment過程?有什麼好的策略嗎?一般來說,github是一個非常好用的central repo hosting service。在github中儲存著專案的所有歷史資訊,master branch作為穩定可靠的可以deployment的分支。在depolyment server上一般也會從github上clone一個repo,當我們在自己的開發主機上完成編碼和測試工作後,打一個tag,git push origin master將會把所有工作上傳到github中分享,這時我們如何自動觸發production server來部署呢?一種方法是登陸到production server上,隨後git pull,git archive, copy到我們的部署目錄中去;另外一種可行的方法是:將部署伺服器上被clone的repo作為我們開發主機repo的一個remote,我們push到github上面的同時,push到deployment server上去,同時在deployment server上利用git的server側hook機制,觸發git archive,並且部署到相關目錄中。具體方法是:git push gituser@productionserverIP:/directory/to/deployed/repo/ master:production 注意這個命令中master是開發主機的branch,production是depoyment這個機器的branch。一般地,在開發流程中,我們還應該再建立一個remote repo作為staging的環境,這樣我們在開發過程中,一旦develop上的開發工作有了階段性的成果,會拉出一個pre-release的分支,打上標籤,push到staging主機上去,供QA測試
  • 如何將已經tracked檔案從git tracking中刪除(並不刪除檔案)?
    # Do this on all machines
    echo "FILE_NAME" >> .gitignore
    git rm --cached FILE_NAME
    git add -u
    git commit -m "removing files from version control"
    # Sync with your git server, pull to sync and push to register your local change
    git pull
    git push

     

  • 如何搭建自己的git server?以下資源可供參考:

https://git-scm.com/book/it/v2/Git-on-the-Server-Setting-Up-the-Server

http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/00137583770360579bc4b458f044ce7afed3df579123eca000

https://github.com/progit/progit/blob/master/zh/04-git-server/01-chapter4.markdown

http://www.centoscn.com/CentosServer/ftp/2014/0414/2789.html

http://freeloda.blog.51cto.com/2033581/1410562

https://www.digitalocean.com/community/tutorials/how-to-set-up-a-private-git-server-on-a-vps

https://www.linux.com/learn/tutorials/824358-how-to-run-your-own-git-server

http://www.linux-magazine.com/Online/Features/Install-Your-Own-Git-Server

http://blog.csdn.net/csfreebird/article/details/7204345

http://wiki.ubuntu.org.cn/Git%E6%9C%8D%E5%8A%A1%E5%99%A8Gitosis%E5%AE%89%E8%A3%85%E8%AE%BE%E7%BD%AE

  •  為了確保master分支的穩定,必須對master分支做好控制(甚至develop分支也要控制),那如何控制向master分支的push操作呢?如果使用Github,最好的策略是: 除了原始master repo分配給deployment manager外,先fork出一個staging repo分配給system integration manager,每一個開發人員都從這個staging repository(從master repo fork來的)(注意:如果有大的feature team,則可以再增加一級:feature team leader fork一個repo作為整個team協同工作的repo)來fork出自己的repo,每一個人都在本地開發後push到自己fork出來的自己有寫許可權的repo,開發人員在自己的repo中開發測試完畢後,pull request提交到staging repo,這時system integration manager召集專家和相關team member來做review(如果可以fast forward的,則無需review),隨後確認接受後就放到staging repo的develop分支,正式宣佈接受開發人員完成的一個feature變更。一旦有feature落地,則應該觸發QA過程,QA過程中發現的問題提交bug給team leader。具體怎麼知道應該給哪些team leader呢?QA人員應該使用git bisxx功能,給出問題是一直存在的還是後來引入的,如果是新程式碼引入的,那麼是哪個feature落地帶來的呢?依據這些資訊就能找到應該找誰來進一步處理。如上面所說,如果feature較大,需要至少2個人人以上來開發,那麼就需要指定feature team leader,同時將staging repo的collabarator為每個team leader開放許可權?team leader可以往staging repo的dev下有Push許可權。QA完成後,可以打tag,由整合測試經理執行merge到master的動作,並且向master repo發pull request。最後由資訊整合官確認ok,部署程式碼,負責運維。
  • 如果在上面描述的工作流中,我們不使用github,而是自建git server,則可以在服務端通過hook來實現這個許可權的控制。
  • 如何既能在feature分支上保留詳細的歷史資訊又能在master分支上只保持一個一個feature粒度的commit?

在feature開發中,我們鼓勵及時commit,這個時候變更管理的粒度是很小的。但是對於一個產品級別的管理者來說,他們可能只關心一個個feature級別的變更,因此當需要將feature落地到master/develop分支上時,我們可以通過下面的策略來執行(先在featureX分支上和master merge並且測試完成,結果Ok後,再在master分支上做git merge --squash完成程式碼落地):

git checkout featureX
git merge master //首先在featureX分支上將featureX分支和master分支做merge並且做好測試工作,之後再在master分支上執行git merge --squash featureX只保留一個歷史
git checkout master git merge
--squash featureX//通過這條命令將featureX的所有commit都合成一條放到master分支

對於小的feature,最好使用git pull --rebase, 大的feature,最好使用git merge --no-ff這樣保留一個commit節點能夠描繪出merge這個重要動作。

或者說: 本地開發 相同的分支總是 git pull --rebase(比如master,develop分支總是這個策略), 在本地合併分支時總是 git checkout master, 對於小的feature,則git merge --squash featureX  :主要作用是featureX的歷史細節只在local repo中保留,中央庫中只保留feature級別的commit;對於大的feature我們則使用git checkout master, git merge featureX  --no-ff 這樣的好處是既能保留大feature的歷史資訊,又能使official庫能大體看到版本變遷歷史的大粒度檢視;還有也可以對featureX的commit使用git rebase -i 來重寫歷史梳理乾淨

git merge --squash featureX 

Hosted GIT repository: Github, BitBucket;

Selft Managed: Gitosis, Gitorious

  •  git clone --recursive git://github.com/nvie/gitflow.git  :使用--recursive引數會自動將repo中的submodules一起clone下來
  •  如何免密碼push遠端repo? a)建立ssh私鑰和公鑰,將公鑰放到github/codingnet的配置頁面上去;b)將remote repo的connection中的url修改為ssh方式的, 比如git@git.coding.net:xxxx/yyyy.git 

當git checkout到不同的branch時,相應目錄看到的東西是不一樣的。這個是檔案系統的功能,比較神奇啊

git checkout -- fileToDropChange   如果有檔案被修改但是又還沒有staging,上述命令則徹底丟棄local的變更;git checkout -- . 丟棄當前目錄中所有的local change(從index區域獲取fileToDropChange的內容覆蓋工作區)  

http://eagain.net/articles/git-for-computer-scientists/  :Git internal

http://www.vogella.com/tutorials/Git/article.html#gitremotebranch_overview  Git commands

http://blog.csdn.net/ithomer/article/details/7529841 

如何找回偶然被刪除的commit?

1. get reflog列出所有操作歷史;

2. 找到對應的commit,建立一個branch : git checkout -b urgentbranch xxxcommit

3. git co dev/git merge urgentbranch

以上三步就能恢復你想要的歷史commit了!

如何強制pull遠端的branch?

有時候一個branch發生衝突,我們已經解決並且push了,這時可能希望強制pull成遠端分支的內容,解決辦法:

1. git fetch --all //獲取所有遠端內容

2. git co yourbranch

3. git reset --hard origin/yourbranch

上述三步解決問題!

如何列出兩個branch之間的commits區別?

git show-branch stock-information staging/master master :列出兩個分支之間的詳細區別列表

! [stock-information] WIP: Link to data series
 ! [staging/master] Add a description to Stock
  ! [master] Display Stocks
---
+   [stock-information] WIP: Link to data series
+   [stock-information~1] Create DataSeries for Stocks.
++  [staging/master] Add a description to Stock
++  [staging/master~1] Import external Stock information
+++ [master] Display Stocks

git log --oneline --no-merges feature/xx..dev 列出現在的從feature/xx分支到dev分支之間的未被merged的commits列表(一般的fast forward merge commit不會列出來!),也就是說在dev上但是卻未能出現在feature/xx分支上的所有commit

解讀:

http://openwares.net/linux/git_show_branch_output.html

輸出分為上下兩部分,使用短劃線”-“分隔。兩個分支使用兩個短劃線”–“,三個分支使用三個短劃線”—“,依次類推。
上半部分為層次縮排的分支列表,下半部分為commit列表。
上半部分的分支列表中,使用*標識當前分支,其他分支使用!標識。分支前的識別符號*或者!一直垂直貫通到下半部分,這一垂直列的符號都是屬於這個分支的。
下半部分的commit列表中,前導的符號有*和+號。*表示這一列上的分支(當前分支)有此commit。而+表示這一列上的分支(非當前分支)有此commit。

識別符號的顏色只是用於容易區分列,一列的顏色是一致的,看起來更清楚。

windows下symlink的支援

很多時候存在這樣的場景:linux、windows混合環境在git專案開發中存在。在linux下存在symlink的概念,windows中從win7開始也有了symlink的支援,我們在使用nmp install時會產生很多的node_modules,而這個node_modules中就會有很多以symlink存在。這時,如果我們在linux下面做了git add和git commit,那麼在repo中就存在這樣的symlinks,而一旦在windows中git clone/git checkout就會發現存在問題!原因就是git bash可能不支援symbol link的操作~。解決方案:

1. 配置git的core.symlinks為true

core.symlinks=true

2.啟動git bash時一定要以administrator許可權啟動.

that is it~!

 

git如何untrack已經tracked的檔案?

git rm --cached myFile
git rm -r --cached myDirectory

如何列出兩個commit之間的所有commit變更?

git log --oneline ee8b8e5e6 ^feature/xiaozhao_xiqing_review

 

相關文章