git教程
git簡介
git是一個開源的分布式版本控制系統,用于敏捷高效的處理任何大小的項目。
git工作流程相關概念
首先要理解git是如何工作的,我們先要理解git工作區,暫存區,版本庫的概念。
工作目錄:就是你在電腦里當前工作的環境目錄。
暫存區域:英文叫stage, 或index。一般存放在 ".git目錄下" 下的index文件(.git/index)中,所以我們把暫存區有時也叫作索引(index)。
git倉庫:工作區有一個隱藏目錄.git,這個不算工作區,而是Git的版本庫。
git工作流程
1.在工作目錄中修改文件。
2.暫存文件,將文件的快照放入暫存區域。
3.提交更新,找到暫存區域的文件,將快照永久性存儲到git倉庫目錄。
這里針對的git操作分別為:git add fileName 或者git add *,這是git工作的第一步,將工作目錄中的變化添加到緩存區,相當于形成下一次將要提交的快照。
然后通過git commit -m "cms框架搭建"完成第二步,將文件的快照提交到暫存區域,也就是實際提交改動,此時你的結果已經提交到head,指向你最后一次提交的結果。
最后通過git push origin cms將暫存區的文件,更新到遠程的git倉庫中。
git基本操作
1.查看遠程分支
git branch -a
2.創建分支
git branch branchName.比如:創建cms分支,git branch cms
3.刪除分支(本地)
git branch -d branchName.比如:刪除cms分支,git branch -d cms
4.刪除分支(遠程)
git push origin --delete branchName.比如:刪除遠程cms分支, git push origin --delete branchName.
5.切換分支
git checkout branchName
6.合并分支到當前分支
git merge branchName,比如把cms分支合并到當前分支(加入為agent),那么一定要注意更新本地分支。
7.回滾日志,回退
git reset --hard commit_id ,注意:git reset --hard是回退到當前最新版本號。
8.根據版本號創建tag
git tag -a tag name versionid -m comments
9.提交tag到遠程庫
git push origin --tag
10.獲取遠程tag
git fetch origin tag tagname
11.刪除遠程tag
git push origin --delete tag tagname
12.查看日志
git log
13.暫存當前工作
多人協作時,當你正在agent分支上編輯某文件A,但你需要切換到另一個分支上去,此時你本地正在編輯的文件又不想編輯,這個時候,如果是git checkout cms是無法實現分支切換的。這時,你需要git stash來暫存當前正在進行的工作。然后切換到cms分支修改bug,但是記得你在cms分支修改完bug之后,切換到agent分支時,一定要記得git stash pop,取消暫存的區域,然后才能接著編輯文件A。
14.放棄當前修改
git fetch origin
git reset --hard origin/master
創建代碼倉庫
git init 創建一個新的git倉庫,它用來將已存在但還沒有版本控制的項目轉換成一個git倉庫,或者創建一個新的git倉庫。執行了這個命令之后,會在當前的目錄下增加一個.git文件夾,這就是你的git倉庫,才開始記錄項目版本情況了。
git clone giturl 克隆項目。
git高級—子項目操作
1.使用場景
基于公司的項目會越來越多,常常需要提取一個公共的類庫提供給多個項目使用,但是這個library怎么和git在一起方便管理呢?
我們需要解決下面幾個問題:
- 如何在git項目中導入library庫?
- library庫在其他的項目中被修改了可以更新到遠程的代碼庫中?
- 其他項目如何獲取到library庫最新的提交?
- 如何在clone的時候能夠自動導入library庫?
解決以上問題,可以考慮使用git的 Submodule來解決。
2.什么是Submodule?
git Submodule 是一個很好的多項目使用共同類庫的工具,他允許類庫項目做為repository,子項目做為一個單獨的git項目存在父項目中,子項目可以有自己的獨立的commit,push,pull。而父項目以Submodule的形式包含子項目,父項目可以指定子項目header,父項目中會的提交信息包含Submodule的信息,再clone父項目的時候可以把Submodule初始化。
3.在項目中使用Submodule
使用git命令可以直接添加Submodule:
git submodule add <repo> <destpath>
git submodule add git@github.com:jjz/pod-library.git pod-library
使用 git status命令可以看到
git status
On branch master
Changes to be committed:
new file: .gitmodules
new file: pod-library
可以看到多了兩個需要提交的文件:.gitmodules和 pod-library
.gitmodules 內容包含Submodule的主要信息,指定reposirory,指定路徑:
[submodule "pod-library"]
path = pod-library
url = git@github.com:jjz/pod-library.git
可以看到記錄了子項目的目錄和子項目的git地址信息。
pod-libray內容只保護子項目的commit id,就能指定到對于的git header上,例如:
Subproject commit 4ac42d2f8b9ba0c2f0f2f2ec87ddbd529275fea5
4ac42d2f8b9ba0c2f0f2f2ec87ddbd529275fea5就是子項目的commit id,父項目的git并不會記錄Submodule的文件變動,它是按照commit git指定Submodule的git header。
另外,這兩個文件都需要提交到父項目的git中。
還可以這樣使用命令添加Submodule
git add .gitmodules pod-ibrary
git commit -m "pod-library submodule"
git submodule init
4.修改Submodule
首先需要確認有對Submodule的commit權限。
進入Submodule目錄里面:
cd pod-library/
修改其中的一個文件看下文件的可以用git status查看變動:
git status
modified: pod-library/UseAFHTTP.h
提交Submodule的更改內容:
git commit -a -m'test submodule'
然后push 到遠程服務器:
git push
然后再回到父目錄,提交Submodule在父項目中的變動:
cd ..
然后看一下父目錄有啥變化:
git status
modified: pod-library (new commits)
可以看到pod-library中已經變更為Submodule最新的commit id:
Subproject commit 330417cf3fc1d2c42092b20506b0d296d90d0b5f
需要把Submodule的變動信息推送到父項目的遠程服務器:
git commit -m'update submodule'
git push
這樣就把子模塊的變更信息以及子模塊的變更信息提交到遠程服務器了,從遠程服務器上更新下來的內容就是最新提交的內容了。
總之一句話,提交的時候先提交到子項目,然后再提交到父項目中。
5.更新Submodule
有兩種方式:一種是父目錄下直接更新,一種是先更新子目錄,再更新父目錄。
- 父目錄直接更新
git submodule foreach git pull - 子目錄下更新
>cd pod-library
git pull
>cd ..
git pull
可以看到在Submodule的目錄中,使用git和單獨的一個項目是一樣的,注意更新Submodule的時候如果有新的commit id產生,需要在父項目產生一個新的提交,pod-libray文件中的 Subproject commit會變為最新的commit id。
6.clone Submodule
clone Submodule有兩種方式 一種是采用遞歸的方式clone整個項目,一種是clone父項目,再更新子項目。
- 采用遞歸參數 --recursive
git clone git@github.com:jjz/pod-project.git --recursive
輸出結果:
loning into 'pod-project'...
remote: Counting objects: 57, done.
remote: Compressing objects: 100% (45/45), done.
remote: Total 57 (delta 13), reused 49 (delta 8), pack-reused 0
Receiving objects: 100% (57/57), 18.79 KiB | 0 bytes/s, done.
Resolving deltas: 100% (13/13), done.
Checking connectivity... done.
Submodule 'pod-library' (git@github.com:jjz/pod-library.git) registered for path 'pod-library'
Cloning into 'pod-library'...
remote: Counting objects: 34, done.
remote: Compressing objects: 100% (25/25), done.
remote: Total 34 (delta 8), reused 30 (delta 7), pack-reused 0
Receiving objects: 100% (34/34), 12.95 KiB | 0 bytes/s, done.
Resolving deltas: 100% (8/8), done.
Checking connectivity... done.
Submodule path 'pod-library': checked out '330417cf3fc1d2c
可以看到init Submodule 會自動被clone下來。
-
先clone父項目,再初始化子項目submodule
git clone git@github.com:jjz/pod-project.gitcd pod-project
初始化submodule
git submodule init
更新submodule
git submodule update
運行結果:
Cloning into 'pod-library'...
remote: Counting objects: 34, done.
remote: Compressing objects: 100% (25/25), done.
remote: Total 34 (delta 8), reused 30 (delta 7), pack-reused 0
Receiving objects: 100% (34/34), 12.95 KiB | 0 bytes/s, done.
Resolving deltas: 100% (8/8), done.
Checking connectivity... done.
Submodule path 'pod-library': checked out '330417cf3fc1d2c42092b20506b0d296d90d0b5f'
7.刪除Submodule
git 并不支持直接刪除Submodule,而是需要手動刪除對應的文件:
cd pod-projectgit rm --cached pod-library rm -rf pod-library rm .gitmodules 更改git的配置文件config: vim .git/config
可以看到Submodule的配置信息:
[submodule "pod-library"]
url = git@github.com:jjz/pod-library.git
刪除submodule相關的內容,然后提交到遠程服務器:
git commit -a -m 'remove pod-library submodule'