Linux下Git的初級使用
幾個概念 工作目錄(work tree) 本地倉庫(local repository) 暫存區域 (index)
工作目錄: 就是你可以使用git操作的命令,比如git checkout啦,暫時可以理解爲當前目錄下有.git文件夾的目錄
暫存區域: 所謂的暫存區域只不過是個簡單的文件,一般都放在 Git 目錄中。有時候人們會把這個文件叫做索引文件(index),不過標準說法還是叫暫存區域。
本地倉庫: 就是把暫存區域裏面的文件提交到git能夠管理的和追蹤的倉庫裏面,
先了解一下這3個概念,以後會在實踐中加深理解
服務器端:
[root@gitserver ~]# mkdir /git =>在根目錄下新建一個git目錄
[root@gitserver ~]# cd /git => 進入剛纔新建的目錄
[root@gitserver git]# ls -a => 裏面空空如也,沒有任何隱藏文件
[root@gitserver git]# git --bare init =>初始化一個裸倉庫
Initialized empty Git repository in /git/
[root@gitserver git]# ls -a =>裏面多了一些管理倉庫的配置文件
. .. branches config description HEAD hooks info objects refs
注意!
初始化倉庫有2種方式 git --bare init 和git init 區別有以下2點
1, 用git init 初始化裏面,git目錄下面只有一個.git文件夾,用git --bare init裏面的都是些配置文件,如上操縱 顯示的結果
2, 用"git init"初始化的版本庫用戶也可以在該目錄下執行所有git方面的操作。但別的用戶在將更新push上來的時候容易出現衝突。比如有用戶在該目錄(就稱爲遠端倉庫)下執行git操作,且有兩個分支(master 和 b1),當前在master分支下。另一個用戶想把自己在本地倉庫(就稱爲本地倉庫)的master分支的更新提交到遠端倉庫的master分支,他就想當然的敲了git push origin master:master於是乎出現錯誤 ,因爲遠端倉庫的用戶正在master的分支上操作,而你又要把更新提交到這個master分支上,當然就出錯了,確定一個repository是否爲bare庫的關鍵在於core.bare屬性(boolean型屬性)。core.bare屬性可以有git config命令設置,也可以通過修改config文件的方式設置,conf文件指的就是當前庫下面的conf配置文件,如果這裏 bare = true 那麼即使有.git文件夾也還是不能進行相關操作。 如果使用了git init初始化,則遠程倉庫的目錄下,也包含work tree,當本地倉庫向遠程倉庫push時, 如果遠程倉庫正在push的分支上(如果當時不在push的分支,就沒有問題), 那麼push後的結果不會反應在work tree上, 也即在遠程倉庫的目錄下對應的文件還是之前的內容,必須得使用git reset --hard才能看到push後的內容.
現在我們已經把遠程倉庫搭建好了,不過現在這個倉庫裏面什麼也沒有,趕快添加點東西進 去把,
[root@gitserver git]# mkdir ycjtest
[root@gitserver git]# cd ycjtest
[root@gitserver ycjtest]# vim testdoc =>在倉庫路徑下新建一個文件夾放入testdoc文檔保存退出
注意 : 剛纔那個文件只是保存在了磁盤下面,還沒有往倉庫裏面提交,也就是說現在倉庫裏面還是空空如也,不要試圖在倉庫目錄下面看到倉庫裏面的東西,即使在客戶端提交到遠程倉庫了,在這裏你也看不到提交的內容。到底怎麼看後面我們會講到。
[root@gitserver ycjtest]# git add testdoc
fatal: This operation must be run in a work tree =>報錯啦!對了,這是個bare倉庫,不能進行git命令的相關操作,
注意:這個倉庫只保存git歷史提交的版本信息,而不允許用戶在上面進行各種git操作,如果你硬要操作的話,只會得到下面的錯誤(”This operation must be run in a work tree”),所以對於遠程倉庫,我們初始化的時候最好使用git --bare init命令初始化。
爲了以後方便測試,我們再用同樣的方法在根目錄下新建一個git1倉庫,這裏用git init 進行倉庫初始化,同樣在裏面新建一個ycjtest的文件夾 裏面放1個testdoc的文檔
[root@gitserver git1]# git add . =>當前目錄到添加到暫存區,別忽略了後面的點
[root@gitserver git1]# git commit -a -m 'testycj hello' =>提交所有暫存區的文件到倉庫
[master (root-commit) 56f8557] testycj hello
Committer: root <root@gitserver.(none)>
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly:
git config --global user.name "Your Name"
git config --global user.email [email protected]
If the identity used for this commit is wrong, you can fix it with:
git commit --amend --author='Your Name <[email protected]>'
1 files changed, 1 insertions(+), 0 deletions(-) =>從這裏可以看出提交了幾個文件
create mode 100644 testycj/testdoc
如何添加空文件夾到暫存區?git 和 svn 不同,僅僅跟蹤文件的變動,不跟蹤目錄。這麼設計是有原因的。但這會帶來一些小麻煩。有時候,確實需要在代碼倉庫中保留某個空目錄。比如測試時需要用到的空目錄。變通的解決辦法是在空目錄下存一個 .gitignore 文件。然後 git add 此目錄後,相當於跟蹤了 .gitignore 文件,產生的“副作用”就是這個“空”目錄也納入“跟蹤”,最終的效果是可以 check out 出一個看起來空空的目錄。如果有許多這樣的空目錄,可以用下面的命令自動補充 .gitignore 文件:find . \( -type d -empty \) -and \( -not -regex ./\.git.* \) -exec touch {}/.gitignore \;然後 git add -f . -f是強制添加的意思,然後提交到倉庫都可以了,
遞歸找尋當前目錄下,類型爲目錄,且爲空,也沒有 .git 開頭的文件,在其中用 touch 新建一個空的 .gitignore 文件。
客戶端:
客戶端以window爲例,如果通過ssh協議連接到遠程倉庫的話,推薦用ssh密鑰對,免密碼登陸,可以先用gitbash工具生成密鑰對,公鑰發給git管理員,私鑰保存到當前用戶目錄下.ssh文件夾下面。以後工作都是在eclipse下面,所以你必須把你的私鑰存放位置在eclipse下面配置
注意:管理員負責把公鑰添加到服務器指定用戶(比如eos)下面的.ssh目錄下面的authorized_keys文件裏面,只有這樣,當你用eos用戶連接遠程倉庫的時候,你的私鑰纔可以和服務器的公鑰配對成功
下面從遠程克隆一個git倉庫到工作空間 ,紅色箭頭指的是克隆圖標
我不是採用密鑰對登陸的,所以需要輸入root的密碼
這個倉庫將存放到本地哪個地方
剩下的Next即可,克隆之後發現git倉庫多了一個叫git166的就是我們剛纔克隆的遠程倉庫,
打開Wording Directory路徑下面,剛纔在服務端創建的文件到了本地的工作路徑
打開裏面的testdoc文檔,修改裏面的內容,添加一行註釋,保存
然後選擇項目右鍵,commit
如果是用戶/密碼push遠程倉庫的話,需要輸入密碼在這裏,ssh密鑰則不需要
如果出現服務器拒絕push的話,
error: refusing to update checked out branch: refs/heads/master
則需要修改服務器端倉庫配置文件,加上後面2行的
注意:如果使用了git init初始化,則遠程倉庫的目錄下,也包含work tree,當本地倉庫向遠程倉庫push時, 如果遠程倉庫正在push的分支上(如果當時不在push的分支,就沒有問題), 那麼push後的結果不會反應在work tree上, 也即在遠程倉庫的目錄下對應的文件還是之前的內容,必須得使用git reset --hard才能看到push
服務器端操作
[root@gitserver testycj]# cat testdoc ==.>雖然已經push到倉庫,工作空間還是原樣
hello world testdoc
[root@gitserver testycj]# git reset --hard ==》徹底回退到某個版本並刷新工作空間
HEAD is now at 6e87c18 commit from client
[root@gitserver testycj]# cat testdoc ==》再次查看,發現顯示了剛纔提交的內容
hello world testdoc
<!--add a comment-->
可以看出剛纔修改的內容已經提交到倉庫裏面了。
reset命令有3種方式:
git reset –mixed:此爲默認方式,不帶任何參數的git reset,即時這種方式,它回退到某個版本,只保留源碼,回退commit和index信息
git reset –soft:回退到某個版本,只回退了commit的信息,不會恢復到index file一級。如果還要提交,直接commit即可
git reset –hard:徹底回退到某個版本,本地的源碼也會變爲上一個版本的內容
以下是一些reset的示例:
(1) 回退所有內容到上一個版本
git reset HEAD^
(2) 回退a.py這個文件的版本到上一個版本
git reset HEAD^ a.py
(3) 向前回退到第3個版本
git reset –soft HEAD~3
(4) 將本地的狀態回退到和遠程的一樣
git reset –hard origin/master
(5) 回退到某個版本
git reset 057d
(7) 回退到上一次提交的狀態,按照某一次的commit完全反向的進行一次commit
git revert HEAD
Eclipse幾個圖標
向上的箭頭有關1表示,本地倉庫提交了1次,向下的箭頭有個1表示服務器那邊有了1個改動,你只有先把這個改動fetch下來,你纔可以提交上去。
箭頭在哪裏標着,就代表當前版本是哪個,版本不一樣,到時候的工作空間裏面的內容是不一樣的。