Git
1. Git簡介
1.1 git是什么
1.1.1概念
Git:git是一款開源的分布式的版本控制軟件
Github:是一個基於git的面向開源及私有軟件項目的托管平台
因僅支持git 作為唯一的版本庫格式進行托管 故名gihub
1.1.2.Git的特點
①Git從服務器上克隆完整的項目到本機,相當於每一個開發者都擁有一個項目的完整版本
②開發者在自己的機器上創建分支,修改代碼.
③將自己本地創建的分支提交到本地的版本庫
④在單機上合並分支
⑤新建一個分支,把服務器上的最新版的代碼fetch下來,然后跟自己的主分支合並
⑥Git最大的亮點在於分支的管理.
1.2 什么是版本控制
版本控制概念:
這種方法是工程圖(engineering drawings)維護(maintenance)的標准做法, 它伴隨着工程圖從圖的誕生一直到圖的定型。 一種簡單的版本控制形式,例如,賦給圖的初版一個版本等級“A”。當做了第一次改變后,版本等級改為“B”,以此類推等等.
1.2.1未引入版本控制的問題:
現實開發中最麻煩的是多人開發中的版本控制,如果未引入版本控制的概念,我們服務器上僅存在一個我們從最初開始開發的項目,我們每一次的增刪改也是在這個項目之上,所以如果某一個開發者提交了帶有bug的代碼,或者對這個已經存在的項目進行更新操作,如果更新失敗,則這個項目就廢棄了
一個項目如果有多個人開發,開發人員A,B,C,分別對項目中的同一代碼進行了修改,那后一次提交的人的代碼,就會覆蓋前一個人的代碼
1.2.2傳統的集中式版本控制
集中式版本控制系統(Centralized Version Control Systems,簡稱 CVCS),版本庫是集中存放在中央服務器的,而干活的時候,用的都是自己的電腦,所以要先從中央服務器取得最新的版本,然后開始干活,干完活了,再把自己的活推送給中央服務器
這么做最顯而易見的缺點是中央服務器的單點故障。如果維修一小時,那么在這一小時內,誰都無法提交更新,也就無法協同工作。如果中心數據庫所在的磁盤發生損壞,又沒有做恰當備份,毫無疑問你將丟失所有數據——包括項目的整個變更歷史.
1.2.3使用分布式版本控制系統
分布式,當我們連接共享版本庫時,可以先將服務器上的項目,克隆到本地,相當於每一台電腦上都有整個項目的文件備份,在沒有網時也可以開發,完成開發后,可以先提交到本地倉庫,當有網的時候,再提交到共享版本庫,這樣一來,如果我們的服務器或者我們自己的電腦出故障,我們也沒有任何擔心
1.3Git的安裝
①下載軟件https://git-scm.com/官網地址
②進行安裝
最重要的一步,其它可以直接走默認
選擇這一步可以直接將我們的git命令,添加到系統變量中
2. git入門
工作區,暫存區,主分支的概念
獲取幫助
git help
如果向對某個具體的命令獲取幫助,可以使用 git help <verb>
2.1設置開發者的個人信息
多人開發的項目中,通過設置的用戶名來區分開發者,設置email來聯系開發者
2.1.1配置當前項目中的用戶信息(局部)
先創建一個本地版本庫
在配置當前項目的用戶信息時,需要進入git管理的項目中來進行設置
1.配置用戶名:Git config user.name “用戶名” 用來區分誰開發的代碼
2.配置郵箱信息:git config uer.eamil “郵箱” 可能是多個國家的開發者,便於聯系開發者
配置以后會可以在隱藏的.git文件夾的config文件中查看到,
也可以使用git config –list進行查看
2.2.2配置全局用戶信息
1.配置用戶名:git - -global config user.name “用戶名” 用來區分誰開發的代碼
2.配置郵箱信息:git - -global config uer.eamil “郵箱” 可能是多個國家的開發者,便於聯系開發者
可以在C:\Users\Administrator\.gitconfig中查看
2.2創建倉庫
①創建文件夾E:\Mygit
②初始化倉庫:
進入我們創建的文件夾 cd e:\Mygit ,使用命令 git init進行初始化倉庫
這時候會在當前文件夾下創建一個.git隱藏文件夾,.git文件夾是我們的倉庫信息,一定不要修改
③對倉庫信息進行配置,主要是設置user.name和user.email,如果設置了全局的用戶信息,可以忽略
2.3添加文件
在倉庫中添加一個hello.java的文件
① 查詢倉庫的狀態:git status
② 將文件加入到暫存區:git add 文件名
使用git status 再次查詢出文件的狀態
現在的文件並沒有真正的提交到主分支上(主分支就是我們真正要運行的程序的所有代碼).
③ 提交到本地版本庫:git commit –m”注釋信息”
git commit -m"創建一個java文件"
此時文件就被提交到了主分支上
查詢指定文件的日志記錄:git log 文件名 如果出現end 使用q退出
74d914fdda87ba20f52b907413fb7eb3a29973de是我們的版本號
總結:
每一次修改或者創建新文件時,都需要先使用 git add 文件名 的命令來將文件添加到緩存區,再使用git commit –m “注釋信息” 來將我們的文件添加到版本庫
或者使用簡化命令 git commit –a –m”注釋信息” 來將我們的文件添加到版本庫
2.4修改文件
Git 如何管理修改的文件
① 將我們之前創建的Hello.java文件進行修改
查詢當前倉庫狀態 git status
以上看到git的一個建議
(use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) |
我們可以選擇git add進行添加到緩存,或者我們可以使用git checkout進行恢復
使用 git diff HEAD Hello.java可以查看我們對文件具體做了哪些修改
② 使用git add 文件名,將文件加入到緩存
③ 使用git commit –m”注釋信息” 提交到本地版本庫
如果進行了vim編輯器,首先Esc退出輸入狀態,然后Shift+;,再輸入q!或wq!(不保存改動,wq!是保存文件的寫入修改)退出
2.5.Git工作區與緩存區
工作區:包含.git文件夾的文件夾(除了.git文件夾)
倉庫:也稱為版本庫,這個不算工作區
暫存區:.git版本庫中有很多東西,包括重要要的稱為stage 的暫存區,還有git為用戶
自動創建的主程序分支master,以及指向master的HEAD指針,HEAD指針永遠指向我們當前項目的最高版本
這個就像我們之前學習的mysql數據庫中的事務一樣,使用insert 增加了,但是沒有使用commit是不會成功的
當使用commit后,會清空暫存區的內容
2.6 版本回退
我們每次提交代碼后,都會生成一個40位的哈希值, 可以成為commit id
使用git log來查看我們的提交記錄
可以使用git show +版本號來查看修改 此版本號的修改內容
2.6.1恢復到上一版本
使用git reset - - hard HAED~1 或使用git reset - - hard HEAD^
2.6.2恢復到指定版本
①查詢當前的日志信息 git reflog
Git log 和git reflog的區別:
git log只會查詢歷史有效版本的版本號
git reflog 會查詢歷史所有版本的版本號,包括已經廢棄的
②找到想要恢復的版本號 使用 git reset –hard 版本號,進行恢復到指定版本
2.7撤銷修改
2.7.1 未執行 git add 添加到緩存區時
可以使用 gid checkout - - Hello.java 與本地倉庫中進行對比,同步
切記用於恢復文件時,文件名前面有--
2.7.2 已經執行git add 添加到了暫存區,但是沒有執行git commit
可以使用 git reset HEAD Hello.java 將暫存區的內容恢復到了工作區
如果文件有錯誤,想恢復到上一次提交,還可以直接使用gid checkout - - Hello.java進行恢復
2.8刪除文件
①.從磁盤上刪除文件
還是可以使用git恢復的命令進行恢復
如果使用
刪除文件,git rm <filename>
刪除文件夾,git rm –r <文件夾名>
同時時候git commit時本地倉庫中的文才會刪除
3 Git和github
3.1注冊賬號
3.2生成SSH Key
使用git bash生成
Ssh-keygen –t rsa –c 429189785@qq.com
會生成兩個文件
id_rsa –私鑰
id_rsa.pub ---公鑰
在github 的setting中選擇SSH Keys 進行添加
將公鑰的內容,粘貼進去
3.3添加遠程倉庫
①將本地已有倉庫與遠程倉庫相關聯
使用命令 git remote add origin https://github.com/zhaoqinrong/admin.git
Git remote add origin+遠程倉庫地址
但是目前為止,遠程倉庫中沒有我們本地倉庫的內容
②將本地所有內容,提交到遠程倉庫
使用命令git push –u origin master
會提示輸入github的用戶名和密碼
由於是第一次推送,而且推送的為master分支,就會使用”-u”的參數將遠程master與本地master進行關聯
④ 修改本地文件后,提交到本地版本庫add 和commit命令
⑤ 推送到遠程倉庫 git push
3.3 克隆倉庫
將遠程版本庫克隆到本地
① ,在github上建立倉庫,並進行初始化
勾選Initialize this repository with a README初始化這個倉庫
② 克隆遠程倉庫
點擊Clone or download,將倉庫的地址復制下來
使用git clone +遠程倉庫地址,對遠程倉庫進行克隆
這樣就克隆下來了
③ 在我們克隆的倉庫中進行項目的開發,這里我們新建一個hello.java的文件 並使用add和commit命令進行本地版本庫的提交
④ 使用git push –u origin master 進行推送 Master為分支名
3.4克隆其他開源項目
① 找到需要克隆的開源項目的地址,然后fork到自己的遠程倉庫
② 復制自己倉庫中這個項目的地址
③ 使用 命令
Git clone +遠程倉庫地址 進行克隆
3.5如何從遠程倉庫中獲取更新
①遠程倉庫與本地倉庫進行關聯
要向從遠程倉庫中獲取更新,必須先將本地倉庫與遠程倉庫進行關聯,可以使用
git remote add origin https://github.com/zhaoqinrong/Mygit
可以使用命令git remote rm origin刪除關聯的遠程倉庫
使用git remote show origin來查看ms遠程倉庫的具體分支
使用git remote –v 來查看與當前本地倉庫相關聯的遠程倉庫
origin為我們為遠程倉庫起的別名
③ 使用git pull origin master進行獲取並合並到本地倉庫
如果直接使用git pull可以會出錯,建議先git fetch到本地,然后使用git merge 合並
3.6 如何向遠程倉庫推送更新
我們編寫項目后,需要將我們的項目推送到遠程倉庫
可以使用git push <url> <本地分支名>
① 遠程倉庫與本地倉庫進行關聯
② 推送更新
建議我們推送更新前都先使用pull獲取遠程倉庫中的更新,然后在push推送
Ms 是我們遠程倉庫的一個別名,我們自定義
可以使用git push ms master:mygit-1
將本地的master分支推送到ms遠程倉庫的mygit-1分支中
3.7刪除遠程倉庫中的文件
①先要將本地倉庫和遠程倉庫進行關聯
進入到我們的git命令行頁面后,先將遠程代碼pull到本地,保持本地倉庫跟遠端倉庫同步。
④ 使用git rm 文件名 刪除 文件
⑤ ,進行提交(和數據庫事務一樣,提交后才會處理)
⑥ 向遠程倉庫進行推送
4分支管理
Master 主分支,主要作為程序的發布
所以不能在master上進行開發,所以應該建立子分支進行開發
4.1 HEAD指針和Master指針
①在沒有分支的情況下,Master指針永遠指向當前的最高版本
而head指針指向master
|
② 創建了新分支,HEAD指向了
|
|
|
|
③ 主分支和子分支進行合並
|
|
|
4.2分支創建
①創建分支:
使用命令 git branch + 分支名
使用git branch 查看當前項目的分支
⑦ 切換分支 使用命令 git checkout +分支名
⑧ 使用命令git checkout +分支名 切換到主分支,然后刪除分支 使用命令 git branch –d +分支名
注意:要刪除分支,必須要先切換到主分支
可以使用 git checkout –b +分支名 創建並切換分支
分支上的文件是相互獨立的,修改文件不會影響
模擬:建立兩個分支,並分別進行推送
先連接遠程倉庫 git remote set-url origin https://github.com/zhaoqinrong/mygithub.git
然后分別推送分支 git push origin master git push origin brh
推送成功后可以在我們github上進行查看
4.3合並分支
①切換回主分支git checkout master
② 合並分支git merge brh(子分支名)
③,刪除子分支 git branch -d brh
③ 推送到遠程倉庫 git push origin master
現在在本地沒有brh的子分支,但是遠程倉庫中的子分支還在
④刪除遠程子分支git push origin –delete brh(子分支名稱)
4.4 刪除分支
刪除本地分支:git branch –d <branch-name>
刪除遠程分支: git push origin –delete <branchName>
4.4 解決代碼沖突
git fetch origin master
git merge origin/master
代碼沖突如何產生的:
當我們在分支上進行開發的時候,難免遇到別的開發人員和我們自己向倉庫中提交相同的代碼
比如我們有一個商城的項目,開發人員A和開發人員B都對同一段代碼做了修改,當A進行提交后並push到遠程倉庫中master合並,B再進行提交並與遠程倉庫中的master進行合並
這時候就會出現代碼沖突
現在我們來模擬一下代碼沖突,並試圖解決
① 在E盤新建文件夾 GitConflict,並初始化倉庫git init
② 在工作區創建名為Conflict.txt的文件,並寫上hello git
③ 把文件提交到本地倉庫
④ 創建新分支,名為Conflict並切換
⑤ 在conflict分支下對Conflict.txt文件進行修改
⑥ 然后在conflict分支下進行提交
⑦,切換到主分支
⑧ 再次對文件進行修改
⑨ 提交修改后的文件
⑩ 和分支conflict進行合並
文件報錯,有沖突
然后我們可以打開倉庫中的Conflict.txt文件進行查看
中間內容表示有沖突的地方,我們可以選擇保留一條信息,進行合並,假如我們保留一下數據
再次提交並合並
OK了
5.使用tag
發布一個版本時,我們通常先在版本庫中打一個標簽(tag),這樣,就唯一確定了打標簽時刻的版本。將來無論什么時候,取某個標簽的版本,就是把那個打標簽的時刻的歷史版本取出來。所以,標簽也是版本庫的一個快照。
打標簽命令:git tag <tagname>
在以往歷史中的提交id上打標簽
使用 :git tag <tagname> <commitid>
刪除標簽 git tag -d<tagname>
5 eclipse中使用git
5.1用eclipse將項目保存到github中
1首先注冊github
2.使用eclipse生成一個SSHkey
3.在github上對進行添加
4.在github上創建一個新的倉庫,並對倉庫進行初始化
5.將我們的項目發布到剛剛創建的倉庫中
因為我們這里是新項目,所以選擇創建一個repository
表示我們的項目還沒有指針
將項目提交到本地倉庫
寫上注釋,選上所有文件進行commit and push
選擇master分支
正在推送
成功
這是我們成功發布的項目,提交給github托管,當我們需要對項目進行修改的時候
5.2我們可以將項目從github上導入到本地
打開MyEclipseàfileàimport
正在導入
導入完成,然后我們在這個項目上進行開發,不會影響到我們倉庫中的項目的完整性
目前是master分支,我們需要新建分支進行我們的開發
新建分支后,自動切換分支
5.3在分支上進行開發,並git到github分支上
1.現在我們已經切換到了上一節創建的分支上,現在我們在我們之前的項目上做一點修改
這是我在MyJindong分支上對項目進行的一個修改,新增了一個aaaaa.html的文件
2.先將我們修改的項目git到本地的倉庫進行一次commit
2. 將更新推送到遠程倉庫,並自動創建分支
這是檢查本地和遠程倉庫的差異:
檢查出本地和遠程倉庫有差異,可以進行,然后在倉庫中創建新分支,將我們的修改后的項目git到遠程倉庫
3.這是我們的新分支和master分支,這就成功的,將新分支git到了遠程倉庫
5.4將我們分支開發的項目和master分支的進行合並
我們第一版的項目有bug,我們在新分支上進行修改,將修改后的項目與我們的之前的項目進行合並
- 首先我們要確定我們要與哪個分支合並,然后將我們的項目切換到哪個分支下,然后使用Merge進行合並
我們這里要與主分支合並,首先切換到主分支,看主分支是否有更新,然后我們合並到本地項目
選擇我們修改的項目進行本地合並
合並后的結果
- 然后選擇push to upstream進行檢查,是否有更新需要上傳到我們的遠程服務器
這是合並到遠程倉庫的結果.成功
5.5刪除本地分支和遠程分支
選擇以后點擊OK即可
5.6版本回退
便可以進行版本的回退
5.7 使用eclipse解決代碼的沖突
模擬
①從遠程倉庫中導入一個項目到我們的eclipe中
導入過程不過講解
這是我們導入的項目,並進行本地版本庫的提交
②創建新分支
並對項目內容進行修改.然后提交到本地版本庫
④ 切換到主分支master,對項目進行修改,並提交本地版本庫
⑤ ,與conflict分支進行合並
便出現了我們期待的結果
⑥ 查看沖突的代碼
標紅的文件代表有沖突
⑦ 查看沖突的代碼
雙擊
紅色框起來的代碼就是有沖突的代碼,再手動進行修改
假設我們現在修改左側的代碼為
再次提交,然后合並查看效果
注意:如果git pull失敗,則需要添加參數
[remote "origin"]
url = https://github.com/zhaoqinrong/test.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master