git 安裝使用和版本管理說明
1. 基本概念
工作區:
實際工作使用代碼和文件。
暫存區:
.git/index 把暫存區有時也叫作索引(index)。目錄樹索引,使用 git add 或 者 git del 會更新,提交文件第一步先要加入暫存區
本地倉庫:
git commit -m “提交說明”。 提交暫存區文件
遠端倉庫
推送到遠端倉庫 git push origin master 下載遠端更新本地文件 git pull
2. 在 ubuntu 18.04 linux 搭建 Git 服務器
2.1.安裝 openssh-server
sudo apt-get install openssh-server
2.2.安裝
sudo apt-get install git
2.3.服務器端創建遠端 Git 倉庫
因爲服務器創建git init --bare的xdisk是裸倉庫,裸倉庫可以直接作爲服務器倉庫供各開發者push、pull數據,實現數據共享和同步,不保存文件,只保存歷史提交的版本信息。參考Git裸倉庫和非裸倉庫
mkdir xdisk
cd xdisk
git init --bare /home/zhoujianwen/xdisk/xdisk.git
2.4.客戶端 clone 遠端倉庫
git clone [email protected]:/home/zhoujianwen/xdisk.git xdisk
windows下的Git客戶端無法clone,Linux和mac下的卻可以。
Clement@DESKTOP-TDR4TM2 MINGW64 ~
$ git clone [email protected]:/home/zhoujianwen/xdisk/xdisk.git d:/projects/xdisk3
Cloning into 'D:/projects/xdisk3'...
ssh: connect to host 192.168.31.10 port 22: Connection timed out
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
ssh-keygen -t rsa -C "[email protected]"
拷貝Windows客戶端生成ssh公鑰內容到linux服務器 ~/.ssh/authorized_keys文件內,
分別修改修改.ssh目錄的權限以及authorized_keys 的權限
chmod 644 ~/.ssh/authorized_keys
chmod 700 ~/.ssh
Clement@DESKTOP-TDR4TM2 MINGW64 /d/projects
$ git clone [email protected]:/home/zhoujianwen/xdisk/xdisk.git xdisk
Cloning into 'xdisk'...
[email protected]'s password:
warning: You appear to have cloned an empty repository.
vim Readme
git add --all
git commit -m "the first commit Readme"
git push
git push
在xdisk目錄創建一個Readme文檔,git push後異常:
Clement@DESKTOP-TDR4TM2 MINGW64 /d/projects/xdisk (master)
$ git push
fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin master
查出兩種這個出現的情況:
- 目錄文件的擁有者,將指定文件的擁有者改爲指定的用戶或組,因爲我設置的上傳賬號是zhoujianwen,但是/home/zhoujianwen/xdisk/目錄下的xdisk.git 庫是其他賬號,這樣就要執行chown
chown -vR zhoujianwen *
- xdisk目錄沒有寫權限的話push也會報錯
chmod -R 777 /home/zhoujianwen/xdisk
git push --set-upstream origin master
$ git push --set-upstream origin master
[email protected]'s password:
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (6/6), 440 bytes | 220.00 KiB/s, done.
Total 6 (delta 0), reused 0 (delta 0), pack-reused 0
remote: error: insufficient permission for adding an object to repository database ./objects
remote: fatal: failed to write object
error: remote unpack failed: unpack-objects abnormal exit
To 192.168.31.10:/home/zhoujianwen/xdisk/xdisk.git
! [remote rejected] master -> master (unpacker error)
error: failed to push some refs to '192.168.31.10:/home/zhoujianwen/xdisk/xdisk.git'
git pull
Clement@DESKTOP-TDR4TM2 MINGW64 /d/projects/xdisk (master)
$ git pull
[email protected]'s password:
Already up to date.
在設置了免密操作之後,爲什麼每次git pull和git push都還是要輸入密碼?可以在當前xdisk目錄下輸入git remote -v查看一下遠程服務鏈接,發現@前面是git,這樣肯定會導致每次git push提交都要輸入密碼,因爲我並沒有將git用戶生成ssh公鑰內容拷貝到linux服務器 ~/.ssh/authorized_keys文件內,只拷貝了用戶名爲zhoujianwen的ssh公鑰。
Clement@DESKTOP-TDR4TM2 MINGW64 /d/projects/xdisk (master)
$ git remote -v
origin [email protected]:/home/zhoujianwen/xdisk/xdisk.git (fetch)
origin [email protected]:/home/zhoujianwen/xdisk/xdisk.git (push)
vim 客戶端目錄的xdisk/.git/config,只要將@前的git 修改爲 zhoujianwen即可。
Clement@DESKTOP-TDR4TM2 MINGW64 /d/projects/sample (master)
$ git remote -v
origin [email protected]:/home/zhoujianwen/sample/sample.git (fetch)
origin [email protected]:/home/zhoujianwen/sample/sample.git (push)
現在git pull和git push都可以不用輸入密碼提交了。
Clement@DESKTOP-TDR4TM2 MINGW64 /d/projects/xdisk (master)
$ git pull
Already up to date.
Clement@DESKTOP-TDR4TM2 MINGW64 /d/projects/xdisk (master)
$ git push
Everything up-to-date
其它問題
https://segmentfault.com/q/1010000002425561
解決思路:既然Linux可以,Windows不行,那麼就查找這兩個系統的git客戶端的差異。經過排查,最終了解到Windows git客戶端的ssh客戶端默認使用的是putty,於是手動改成與Linux客戶端一致的OpenSSH。問題解決。
powershell
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Program Files\Git\bin\bash.exe" -PropertyType String -Force
在linux下搭建Git服務器
https://www.liaoxuefeng.com/wiki/896043488029600/899998870925664
https://stackoverflow.com/questions/53834304/how-do-i-git-clone-from-a-windows-machine-over-ssh
最簡單的解決方案是將默認的Windows OpenSSH shell更改爲bash。您可以從Windows機器上的powershell輕鬆完成此操作:
使用git bash輕鬆解決
Clement@DESKTOP-TDR4TM2 MINGW64 ~
$ git clone [email protected]:/home/zhoujianwen/xdisk/xdisk.git /d/projects/xdisk
Cloning into 'D:/projects/xdisk'...
[email protected]'s password:
warning: You appear to have cloned an empty repository.
git book
https://git-scm.com/book/zh/v2/服務器上的-Git-在服務器上搭建-Git
2.5.提交代碼流程
在使用 clone 獲取了倉庫之後,比如修改了其中的 test.md 文件
可以先通過 git status 查看狀態
第一步 git add test.md 添加到暫存區
第二步 git commit -m “提交說明” 將暫存區提交到本地倉庫
第三部 git push 提交到遠端倉庫
2.6.客戶設置用戶名和郵箱
git config --global user.email “[email protected]”
git config --global user.name “Your Name”
3. GIt 日誌查看和代碼回滾
Clone 獲取數據
-(n) 僅顯示最近的 n 條提交
–since, --after 僅顯示指定時間之後的提交。
–until, --before 僅顯示指定時間之前的提交。
–author 僅顯示指定作者相關的提交。
–committer 僅顯示指定提交者相關的提交。
git log --since 2019-07-06
git log --author zhoujianwen
commit 1cd168c9b9afcd300d7e0328506115e35d3b6793 Author: Your Name
<[email protected]> Date: Sat Jul 6 10:11:53 2019 -0700
git log --after "2019-07-09 22:00:00" --before "2019-07-09 23:59:59"
git log --auther zhoujianwen
git log --auther zhou
代碼回滾
vim readme.md
git add readme.md
git commit -m "change error"
git log
cat readme.md
查看當前版本 git reset --hard HEAD
代碼回滾,根據日誌提供的 commit 哈希值,只要取前幾位即可
git push origin HEAD --force
git reset --hard 1cd168c9b //代碼回滾到這個版本號
git add readme.md
git commit -m "add the roll"
git push --force //由於代碼回溯到之前的版本,造成本地代碼版本號與遠程服務器版本號不一致,這時可以強制提交。
在多人協作的情況下,儘量少用強制提交,因爲在衝突處理的情況下,強制提交有可能會造成別人提交的代碼被覆蓋掉,要注意風險。
git log
4. Git 衝突解決
A用戶
Clement@DESKTOP-TDR4TM2 MINGW64 /d/projects/xdisk (master)
$ git remote -v
origin [email protected]:/home/zhoujianwen/xdisk/xdisk.git (fetch)
origin [email protected]:/home/zhoujianwen/xdisk/xdisk.git (push)
Clement@DESKTOP-TDR4TM2 MINGW64 /d/projects/xdisk (master)
$ git pull
Already up to date.
Clement@DESKTOP-TDR4TM2 MINGW64 /d/projects/xdisk (master)
$ cat Readme
cat: cat: No such file or directory
Test~
Test~
update from mac
vim Readme 添加一行內容"update from A user"
git add Readme or git add --all
git commit -m "A user"
Clement@DESKTOP-TDR4TM2 MINGW64 /d/projects/xdisk (master)
$ git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 263 bytes | 131.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To 192.168.31.10:/home/zhoujianwen/xdisk/xdisk.git
08aaacb..c374b3d master -> master
B用戶
Clement@DESKTOP-TDR4TM2 MINGW64 /d/projects/xdisk2 (master)
$ git remote -v
origin [email protected]:/home/zhoujianwen/xdisk/xdisk.git (fetch)
origin [email protected]:/home/zhoujianwen/xdisk/xdisk.git (push)
Clement@DESKTOP-TDR4TM2 MINGW64 /d/projects/xdisk2 (master)
$ git pull
Already up to date.
Clement@DESKTOP-TDR4TM2 MINGW64 /d/projects/xdisk2 (master)
$ cat Readme
Test~
Test~
update from mac
vim Readme < “update from A user”
現在B用戶也修改Readme文件,往Readme文件添加一行"update from A user"
git add Readme
git commit -m "B user"
Clement@DESKTOP-TDR4TM2 MINGW64 /d/projects/xdisk2 (master)
$ git push
To 192.168.31.10:/home/zhoujianwen/xdisk/xdisk.git
! [rejected] master -> master (fetch first)
error: failed to push some refs to '192.168.31.10:/home/zhoujianwen/xdisk/xdisk.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
git push 發生提交遠程衝突了,如何解決衝突呢?拿當前master版本與origin/master遠程服務器的版本做Readme文件內容的對比,
git diff master origin/master
如果差異比較大,可以先把我們的代碼做好備份。而差異比較少,我們就直接git pull成功之後會自動更新,可能會自動合併,合併了衝突文件修改完之後,再來git add 、git commit 、git push,這樣就解決了Readme文件衝突,但是這樣一來容易將A用戶修改與B用戶修改的Readme文件內容做合併處理。
Clement@DESKTOP-TDR4TM2 MINGW64 /d/projects/xdisk2 (master)
$ git pull
remote: 瀵硅薄璁℃暟涓? 3, 瀹屾垚.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), 243 bytes | 2.00 KiB/s, done.
From 192.168.31.10:/home/zhoujianwen/xdisk/xdisk
08aaacb..c374b3d master -> origin/master
Auto-merging Readme
CONFLICT (content): Merge conflict in Readme
Automatic merge failed; fix conflicts and then commit the result.
cat Readme
Clement@DESKTOP-TDR4TM2 MINGW64 /d/projects/xdisk2 (master|MERGING)
$ cat Readme
Test~
Test~
<<<<<<< HEAD
update from B user
=======
update from A user
>>>>>>> c374b3d6de3a3be578444bcf90474412b5ef4f61
vim Readme,修改Readme內容
Test~
Test~
update from B user
update from A user
git add Readme
git commit -m "B user ref"
Clement@DESKTOP-TDR4TM2 MINGW64 /d/projects/xdisk2 (master)
$ git push
Enumerating objects: 10, done.
Counting objects: 100% (10/10), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (6/6), 528 bytes | 176.00 KiB/s, done.
Total 6 (delta 0), reused 0 (delta 0), pack-reused 0
remote: error: insufficient permission for adding an object to repository database ./objects
remote: fatal: failed to write object
error: remote unpack failed: unpack-objects abnormal exit
To 192.168.31.10:/home/zhoujianwen/xdisk/xdisk.git
! [remote rejected] master -> master (unpacker error)
error: failed to push some refs to '192.168.31.10:/home/zhoujianwen/xdisk/xdisk.git'
git push發現寫入失敗,發現遠程服務器的.git目錄的object大部分文件的擁有者都是git用戶,因爲遠程倉庫xdisk是用git用戶初始化的,所以出現權限衝突。只需要登錄到遠程倉庫目錄下遞歸修改所有文件擁有者sudo chown -vR zhoujianwen *
(caffe2_env) zhoujianwen@zhoujianwen-System:~/xdisk$ sudo chown -vR zhoujianwen *
[sudo] zhoujianwen 的密碼:
'xdisk.git/description' 的所有者已保留爲zhoujianwen
'xdisk.git/refs/tags' 的所有者已保留爲zhoujianwen
'xdisk.git/refs/heads/master' 的所有者已保留爲zhoujianwen
'xdisk.git/refs/heads' 的所有者已保留爲zhoujianwen
'xdisk.git/refs' 的所有者已保留爲zhoujianwen
'xdisk.git/config' 的所有者已保留爲zhoujianwen
'xdisk.git/info/exclude' 的所有者已保留爲zhoujianwen
再次git push成功了
Clement@DESKTOP-TDR4TM2 MINGW64 /d/projects/xdisk2 (master)
$ git push
Enumerating objects: 10, done.
Counting objects: 100% (10/10), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (6/6), 528 bytes | 176.00 KiB/s, done.
Total 6 (delta 0), reused 0 (delta 0), pack-reused 0
To 192.168.31.10:/home/zhoujianwen/xdisk/xdisk.git
c374b3d..2858c3f master -> master
B倉庫與遠程倉庫同步完之後,現在A用戶git pull拉取更新本地倉庫
Clement@DESKTOP-TDR4TM2 MINGW64 /d/projects/xdisk (master)
$ git pull
remote: 瀵硅薄璁℃暟涓? 6, 瀹屾垚.
remote: 鍘嬬緝瀵硅薄涓? 100% (3/3), 瀹屾垚.
remote: Total 6 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (6/6), 508 bytes | 1024 bytes/s, done.
From 192.168.31.10:/home/zhoujianwen/xdisk/xdisk
c374b3d..2858c3f master -> origin/master
Updating c374b3d..2858c3f
Fast-forward
Readme | 1 +
1 file changed, 1 insertion(+)
這個就是我們合併更新之後的Readme
Clement@DESKTOP-TDR4TM2 MINGW64 /d/projects/xdisk (master)
$ cat Readme
Test~
Test~
update from B user
update from A user
修改了文檔,pull 時發送衝突,會自動合併到代碼,代碼中指出衝突的位置,修改後再提交
修改了文檔,push 時發送衝突,做好備份,先 pull 後處理完衝突再提交
查看衝突
git diff master origin/master
撤銷修改
直接回到之前的版本 git reset --hard 1cd168c9b
5. Windows 使用 Tortoise Git 安裝使用
5.1.下載安裝
http://ffmpeg.club/tools_download.html
1 安裝 Git-2.22.0-64-bit
2 安裝 TortoiseGit-2.8.0.0-64bit
到一個目錄下面,右鍵 Git Clone
5.2.提交代碼
在項目路徑下右鍵
6. Linux 使用 RSA 公私鑰免密碼提交更新
6.1.服務器端 Git 打開 RSA 認證
進入 /etc/ssh 目錄,編輯 sshd_config,去掉下面配置的註釋:
保存並重啓 ssh 服務:
/etc/init.d/ssh restart
6.2.客戶端創建 SSH 公鑰和私鑰
ssh-keygen -t rsa -C “[email protected]”
此時 用戶路徑.ssh 下會多出兩個文件 id_rsa 和 id_rsa.pub
id_rsa 是私鑰
id_rsa.pub 是公鑰
6.3.添加用戶公鑰到 Git 服務端
將 id.rsa.pub 的內容複製到 Git 服務器用戶的.ssh 目錄下 authorized_keys 文件中,可以有多個。
cat >> .ssh/authorized_keys’ < ~/.ssh/id_rsa.pub
7. Windows 使用 Tortoise Git 免密碼提交
服務端配置和 linux 上一致,主要是 Tortoise Git 工具配置。
打開 PuTTYGen 生成公私鑰匙
有兩種生成方法,第一種就是使用Conversions->Import key 讀取客戶端之前生成的公鑰匙或私鑰匙都可以,它會自動配對生成,讀取成功之後保存id_rsa_putty.ppk鑰匙到目錄C:\Users\Clement.ssh
第二種就是點擊Generate重新生成公鑰匙,並將公鑰匙的內容複製到 Git 服務器用戶的.ssh 目錄下 authorized_keys 文件中,可以有多個。
最後保存私鑰匙爲後綴名ppk的文件。
修改Readme文件內容,免密碼提交成功
8. 版本規劃
版本命名: a-b-c-d
a:主版本號(major version number)。整數,取值範圍:[0,65535]。
b:副版本號(minor version number)。整數,取值範圍:[0,65535]。一般用副版本號表 示版本的穩定性。奇數爲測試版本,偶數爲穩定版本。
a.b – 主版本號與副版本號標識了軟件產品的主要功能特性、代碼分支等,一般在產品規 劃之初制定,並可能與產品銷售許可證緊密相關。
c:發佈號(release number)。整數,取值範圍:[0,65535]。體現軟件產品小的功能變更, 或者反映功能集合定義、產品型號(包括 OEM)等。
d:構建編號(build number)git hash 值取前八位。構建變化更象一種內部編號,用於內 部測試,因此,不要求必須顯示在軟件用戶界面。
a.b.c:對於最終用戶來說,a.b.c 實際上是從所有前三字段同爲 a.b.c 的版本中選取出來 的發佈版本。
a.b.c.d: 對於產品生產者自己來說,需要用 a.b.c.d 來精確指定某一版本。
由於目前有產品基於技術上需要,B,C,D 允許前綴 0,但不允許插入阿拉伯數字以外的字 符。前綴 0 與無前綴 0 表示相同的版本號。 版本號前後的其他信息(產品名稱、編譯發佈時間、alpha/beta 等),與版本號之間用符 號“-”連接。
實例:
第一次編譯版本:
foo-1.0.0.1-200404111030.exe
修改第一批 BUG 之後編譯的版本:
foo-1.0.0.2-200404211543.exe
…
修改第 8 批 BUG 之後編譯的版本:
foo-1.0.0.9-200404280917.exe
經過研發內部測試,認爲此版本是正式發佈版的候選版本,則提升小版本號,編譯 milestone 版本,並提交測試:
foo-1.0.1.1-200405101101.exe
如正式測試流程認定此版本符合需求定義與發佈條件,則此版本即爲正式發佈版。雖然 軟件可以將版本號顯示爲 1.0.1,但它的真實版本號爲 1.0.1.1。 如果 1.0.1.1 不合格,則繼續修改 BUG,編譯版本:
foo-1.0.1.2-200405150432.exe
…
修改第 4 批 BUG 之後編譯的版本:
foo-1.0.1.5-200506031755.exe
經過研發內部測試,認爲此版本是正式發佈版的候選版本,則提升小版本號,編譯 milestone 版本,並提交測試:
foo-1.0.2.1-200506201026.exe
如正式測試流程認定此版本符合需求定義與發佈條件,則此版本即爲正式發佈版。雖然軟件可以將版本號顯示爲 1.0.2,但它的真實版本號爲 1.0.2.1。 如果 1.0.2.1 還不合格,則繼續上述流程,直到產生正式發佈版本。
假設,上一個開發週期的正式發佈版本爲 1.0.5.1,並且 1.0 申請了銷售許可證。新的 開發週期決定在 1.0.5.1 的基礎上調整軟件結構,先確定大版本號爲 2.0。
經過一個階段的開發,編譯了 2.0 的第一個版本:
foo-2.0.1.1-200504211543.exe
…
重複以上過程。