Git
以下內容整理自廖雪峰的git教程,主要用於個人方便使用git命令
git忽略已經被納入版本庫的文件
使用 git update-index –-skip-worktree [file]
可以實現修改本地文件不會被提交,但又可以拉取最新更改的需求。適用於一些不經常變動,但是必須本地化設置的文件
另外還有 git update-index –-assume-unchanged [file]
該命令只是假設文件沒有變動,使用reset時,會將文件修改回去
NOTE: 該方法在使用
add .
命令添加所有文件到暫存區,commit
提交到版本庫,修改內容依然會被加入到版本庫中
重新跟蹤 git update-index --no-assume-unchanged
詳細語法:
git update-index
[--add] [--remove | --force-remove] [--replace]
[--refresh] [-q] [--unmerged] [--ignore-missing]
[(--cacheinfo <mode>,<object>,<file>)…]
[--chmod=(+|-)x]
[--[no-]assume-unchanged]
[--[no-]skip-worktree]
[--ignore-submodules]
[--[no-]split-index]
[--[no-|test-|force-]untracked-cache]
[--really-refresh] [--unresolve] [--again | -g]
[--info-only] [--index-info]
[-z] [--stdin] [--index-version <n>]
[--verbose]
[--] [<file>…]
Reference: git-update-index
git commit without message
Command: git commit -a --allow-empty-message -m ''
or use a global configuration as following
git config --global alias.nccommit 'commit -a --allow-empty-message -m ""'
git簡介
Git是分布式版本控制系統
安裝git后,配置用戶名和email
git config --global user.name "Your Name"
git config --global user.email "email@example.com"
不加--global
參數只對當前倉庫起作用,后面有更詳細的介紹
初始化git repository(版本庫,倉庫)
git init
添加文件到版本庫
git add readme.txt
提交
git commit -m "commit comment"
查看版本庫當前的狀態
git statuss
查看工作區文件修改的內容
git diff
查看提交日志
git log
參數: --pretty=oneline 每個提交日志信息只顯示一行
顯示最后一次提交信息
git log -1
版本回退
git reset --hard 版本號 (或者HEAD)
HEAD:代表當前版本,HEAD^代表上個版本,HEAD^^上上個版本......HEAD~100......
查看使用命令日志
git reflog
撤銷修改
git checkout -- readme.txt
命令git checkout – readme.txt意思就是,把readme.txt文件在工作區的修改全部撤銷,這里有兩種情況:
一種是readme.txt自修改后還沒有被放到暫存區,現在,撤銷修改就回到和版本庫一模一樣的狀態;
一種是readme.txt已經添加到暫存區后,又作了修改,現在,撤銷修改就回到添加到暫存區后的狀態。
總之,就是讓這個文件回到最近一次git commit或git add時的狀態。
git reset HEAD readme.txt
把暫存區的修改撤銷掉(unstage),重新放回工作區.(工作區的文件內容無變化)
刪除文件
在系統中刪除過文件后,需要在版本庫中刪除,使用下面的命令(或者直接使用下面命令):
git rm readme.txt
git commit -m "remove readme.txt"
如果刪錯了,可以撤銷修改,也就是回到版本庫的狀態: git checkout – readme.txt
生成SSH Key
ssh-keygen -t rsa -C "youremail@example.com"
生成后的key在 用戶主目錄/.ssh 下, id_rsa是私鑰, id_rsq.pub是公鑰
遠程版本庫
本地已有版本庫,關聯遠程版本庫:
git remote add origin 遠程版本庫URL
第一次推送
git push -u origin master
-u 參數: 把本地的master分支和遠程的master分支關聯起來,在以后的推送或者拉取時就可以使用簡化命令:
git push origin master
本地沒有版本庫,克隆個新版本庫:
git clone 遠程版本庫URL
默認的git:// 使用ssh協議, 也可以用 https:// 協議
使用https除了速度慢以外,還有個最大的麻煩是每次推送都必須輸入口令
分支管理
創建分支
git branch dev
切換分支
git checkout dev
創建並切換分支
git checkout -b dev
查看當前分支
git branch
git branch
命令會列出所有分支,當前分支前面會標一個*
號
合並分支
將dev分支合並到master分支,先切換到master分支上面,然后執行合並命令:
git merge dev
刪除分支
git branch -d dev
用帶參數的git log 查看分支的合並
git log --graph --pretty=oneline --abbrev-commit
git log --graph
命令可以看到分支合並圖
合並分支時禁用Fast forward 模式
git merge --no-ff -m "merge with no-ff" dev
–no-ff 參數: 強制禁用Fast forward模式
通常,合並分支時,如果可能,Git會用Fast forward模式,但這種模式下,刪除分支后,會丟掉分支信息
如果要強制禁用Fast forward模式,Git就會在merge時生成一個新的commit,這樣,從分支歷史上就可以看出分支信息
BUG分支
儲藏工作現場
git stash
可以把當前工作現場“儲藏”起來,等以后恢復現場后繼續工作
切換到需要修復BUG的分支上(這步不能省略)
git checkout master
在需要修復BUG的分支上創建BUG分支並切換到BUG分支上
git checkout -b issue-101
修復完成后切換到需要修復BUG的分支上
git checkout master
合並分支
git merge --no-ff -m "merged bug fix 101" issue-101
刪除BUG分支
git branch -d issue-101
切換到之前工作的分支上
git checkout dev
查看儲藏工作現場的列表
git stash list
恢復工作現場的兩種方式
git stash apply
恢復后,stash內容並不刪除, 需要用
git stash drop
來刪除
git stash pop
恢復的同時把stash內容也刪了
多次stash
可以多次stash,恢復的時候,先用git stash list
查看,然后恢復指定的stash,用命令:
git stash apply stash@{0}
強行刪除未合並的分支
git branch -D <branch name>
查看遠程版本庫信息
git remote
參數
-v
顯示更詳細的信息
推送本地master分支到遠程版本庫
git push origin master
推送本地dev分支到遠程版本庫
git push origin dev
創建遠程origin的dev分支到本地
git checkout -b dev origin/dev
解決沖突
git pull
先用git pull把最新的提交從origin/dev抓下來,然后,在本地合並,解決沖突(修改完文件后add commit),再推送
指定本地dev分支與遠程origin/dev分支的鏈接
git branch --set-upstream dev origin/dev
創建標簽
切換到需要打標簽的分支上,使用命令: git tag <name>
就可以打一個新標簽
默認標簽是打在最新提交的commit上的
例如: git tag v1.0
查看標簽
git tag
查看所有標簽
注意,標簽不是按時間順序列出,而是按字母排序的
使用commit id 創建標簽
git tag v0.9 6224937
在任意commit點創建標簽
查看標簽信息
git show <tagname>
創建帶有說明的標簽
git tag -a v0.1 -m "version 0.1 released" 3628164
用-a指定標簽名,-m指定說明文字
通過-s
用私鑰簽名一個標簽
git tag -s v0.2 -m "signed version 0.2 released" fec145a
簽名采用PGP簽名,因此,必須首先安裝gpg(GnuPG),如果沒有找到gpg,或者沒有gpg密鑰對,就會報錯
刪除標簽
git tag -d v0.1
推送某個標簽到遠程
創建的標簽都只存儲在本地,不會自動推送到遠程
如果要推送某個標簽到遠程,使用命令git push origin <tagname>
例如:git push origin v1.0
一次性推送全部尚未推送到遠程的本地標簽
git push origin --tags
刪除遠程標簽
先從本地刪除
git tag -d v0.9
然后,從遠程刪除
git push origin :refs/tags/v0.9
配置Git顯示顏色
git config --global color.ui true
ignore 忽略特殊文件
在Git工作區的根目錄下創建一個特殊的.gitignore文件,然后把要忽略的文件名填進去,Git就會自動忽略這些文件
不需要從頭寫.gitignore文件
所有配置文件可以直接在線瀏覽:https://github.com/github/gitignore
如果你確實想添加該文件,可以用-f強制添加到Git
git add -f App.class
檢查文件在.gitignore文件的哪條忽略規則中
git check-ignore -v App.class
配置別名
git config --global alias.<alias> <'git command'>
–global參數是全局參數,也就是這些命令在這台電腦的所有Git倉庫下都有用 配置Git的時候,加上–global是針對當前用戶起作用的,如果不加,那只針對當前的倉庫起作用
每個倉庫的Git配置文件都放在.git/config文件中 當前用戶的Git配置文件放在用戶主目錄下的一個隱藏文件.gitconfig中 刪除別名: 別名就在配置文件中[alias]行后面,要刪除別名,直接把對應的行刪掉即可 配置別名也可以直接修改這個文件,如果改錯了,可以刪掉文件重新通過命令配置
git config –global alias.unstage ‘reset HEAD’
配置別名: 把暫存區的修改撤銷掉(unstage),重新放回工作區
使用:
git unstage test.java
git config –global alias.lg “log –color –graph –pretty=format:’%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset’ –abbrev-commit”
配置別名: 查看合並歷史
搭建Git服務器
Linux: Ubuntu或Debian
第一步,安裝git
sudo apt-get install git
第二步,創建一個git用戶,用來運行git服務:
sudo adduser git
第三步,創建證書登錄:
收集所有需要登錄的用戶的公鑰,就是他們自己的id_rsa.pub
文件,把所有公鑰導入到/home/git/.ssh/authorized_keys
文件里,一行一個
第四步,初始化Git倉庫:
先選定一個目錄作為Git倉庫,假定是/srv/sample.git
,在/srv
目錄下輸入命令:
sudo git init --bare sample.git
Git就會創建一個裸倉庫,裸倉庫沒有工作區,因為服務器上的Git倉庫純粹是為了共享,所以不讓用戶直接登錄到服務器上去改工作區,並且服務器上的Git倉庫通常都以.git
結尾。然后,把owner改為git
:
sudo chown -R git:git sample.git
第五步,禁用shell登錄:
出於安全考慮,第二步創建的git用戶不允許登錄shell,這可以通過編輯/etc/passwd
文件完成。找到類似下面的一行:
git:x:1001:1001:,,,:/home/git:/bin/bash
改為:
git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell
這樣,git用戶可以正常通過ssh使用git,但無法登錄shell,因為我們為git用戶指定的git-shell每次一登錄就自動退出
第六步,克隆遠程倉庫:
現在,可以通過git clone命令克隆遠程倉庫了,在各自的電腦上運行:
$ git clone git@server:/srv/sample.git
Cloning into 'sample'...
warning: You appear to have cloned an empty repository.
剩下的推送就簡單了
管理公鑰
如果團隊很小,把每個人的公鑰收集起來放到服務器的/home/git/.ssh/authorized_keys
文件里就是可行的。如果團隊有幾百號人,就沒法這么玩了,這時,可以用Gitosis來管理公鑰。
這里我們不介紹怎么玩Gitosis了,幾百號人的團隊基本都在500強了,相信找個高水平的Linux管理員問題不大
管理權限
有很多不但視源代碼如生命,而且視員工為竊賊的公司,會在版本控制系統里設置一套完善的權限控制,每個人是否有讀寫權限會精確到每個分支甚至每個目錄下。因為Git是為Linux源代碼托管而開發的,所以Git也繼承了開源社區的精神,不支持權限控制。不過,因為Git支持鈎子(hook),所以,可以在服務器端編寫一系列腳本來控制提交等操作,達到權限控制的目的。Gitolite就是這個工具
這里我們也不介紹Gitolite了,不要把有限的生命浪費到權限斗爭中