1、没有Git
用目录拷贝区分不同版本 成员沟通成本高,代码集成效率低
2、集中式VCS
集中的版本管理服务器 客户端要一直和服务器相连
3、分布式VCS
客户端脱离服务端照样可以管理版本
4、Git
版本控制系统
最优的存储能力,非凡的性能, 开源的,容易备份,支持离线操作,容易定制工作流程
5、GitHub、GitLab为Git做服务
GitHub 全球最大的开源社区,优秀的开源项目,来存储代码
GitLab 有社区版本
https://git-scm.com/book/zh/v2/起步-安装-Git
要配置用户名 和邮箱
前面是配置文件的具体位置,后面是命令
/etc/gitconfig (电脑), git config --system
~/.gitconfig (用户) , git config --global
.git/config (特定项目) , git config --local
git config --global user.name wang 设置全局的用户名
git config --local user.name zhao 设置项目级的用户名
git config --global user.email [email protected] 设置全局的用户名邮箱
git config --local user.email [email protected] 设置项目级的用户名邮箱
git config user.name 查看当前用户名
cat ~/.gitconfig 显示全局用户名
cat .git/config 显示特定项目级的用户名(在特定的git项目下)
当需要在别人的机器上建立自己的git项目,并且想以自己的名字和邮件提交时,就可以设置特定项目级的用户名
用list来查看所设置的所有内容
git config --global --list
git config --local --list
建Git仓库
1、把已有的项目代码纳入Git管理
项目名为 git_learning_directory
cd xxxPATHxxx
git init git_learning_directory
就可以做git add, git commit操作了
mv old_file new_file
git status
git add new_file
git rm old_file
git status
git commit -m 'modify file name'
git mv old_file new_file
git status
git commit -m 'modify file name'
git rm FileName
git status
git commit -m 'remove FileName'
通过图形界面工具来查看版本历史
gitk需要安装
.git 目录结构
drwxrwxr-x. 2 tester tester 6 Jan 31 00:29 branches
-rw-rw-r--. 1 tester tester 48 Jan 31 05:42 COMMIT_EDITMSG
-rw-rw-r--. 1 tester tester 399 Jan 31 04:50 config
-rw-rw-r--. 1 tester tester 73 Jan 31 00:29 description
-rw-rw-r--. 1 tester tester 3530 Feb 6 20:47 FETCH_HEAD
-rw-rw-r--. 1 tester tester 28 Jan 31 00:33 HEAD
drwxrwxr-x. 2 tester tester 242 Jan 31 00:29 hooks
-rw-rw-r--. 1 tester tester 2298904 Jan 31 05:40 index
drwxrwxr-x. 2 tester tester 21 Jan 31 00:29 info
drwxrwxr-x. 3 tester tester 30 Jan 31 00:31 logs
drwxrwxr-x. 73 tester tester 4096 Feb 6 20:41 objects
-rw-rw-r--. 1 tester tester 41 Jan 31 05:42 ORIG_HEAD
-rw-rw-r--. 1 tester tester 16287 Jan 31 00:31 packed-refs
drwxrwxr-x. 5 tester tester 46 Jan 31 00:31 refs
cat HEAD
ref: refs/heads/CurrentBranchName
如果切换了分支,则HEAD文件内容会被改变
cat config
[user]
name = zhao
email = [email protected]
cat config显示的内容可通过如下方法设置及查看
git config --local user.name
git config user.name
ll refs
drwxrwxr-x. 2 tester tester 39 May 23 05:54 heads
drwxrwxr-x. 3 tester tester 20 Jan 31 00:31 remotes
drwxrwxr-x. 2 tester tester 25 May 23 05:53 tags
ll refs/heads
显示的是存在的分支名
-rw-rw-r--. 1 tester tester 41 Jan 31 05:42 BranchName
-rw-rw-r--. 1 tester tester 41 Jan 31 00:31 master
cat refs/heads/BranchName
最新的一次commit的序列号
933ee2he5
查询序列号的类型
git cat-file -t 933ee2he5
是commit
commit
查询序列号的内容
git cat-file -p 933ee2he5
ll refs/remotes/origin/
-rw-rw-r--. 1 tester tester 41 Jan 31 05:42 BranchName
-rw-rw-r--. 1 tester tester 32 Jan 31 00:31 HEAD
-rw-rw-r--. 1 tester tester 41 Feb 6 20:41 master
cat refs/remotes/origin/BranchName
933ee2he5
cat refs/remotes/origin/HEAD
ref: refs/remotes/origin/master
cat refs/remotes/origin/master
b7a39oazz
显示tag信息
一个commit,说明有一次变更,包含 tree(相当于文件夹)、parent、author和committer。
一个commit对应一棵树tree,代表当前commit对应仓库的所有文件夹的快照
一个tree包含tree和blob
一个blob指的就是具体的文件内容
在git中,blob与文件名无关,只与文件内容有关,即文件内容相同,在git中是同一个blob。
输入该命令后,就可以在打开的文件中修改,之后保存退出即可。
git commit --amend
step1: 先通过git log来查看要修改的message的commitID以及它的父亲的commitID
git log -3 oneline
显示如下:
r8utjm9 The fourth commit!!!
58dd00b The third commit
5t889cc The second commit!!!
step2: 想在原来的老旧的commit message最后面加上!!!
要修改的原commit的信息如下:
58dd00b The third commit
想在原来的commit后加上!!!
所以要修改的commit的message对应的commit的id号会变化
step3: git rebase -i 后面 加上commitID
git rebase -i 5t889cc
序列号为要修改的那次commit的前一次,即被变的commit message的父亲
输入上面命令后显示的文件内容如下
pick 58dd00b The third commit
pick r8utjm9 The fourth commit!!!
#Commands:
#p, pick = use commit
#r, reword = use commit, but edit the commit message
#e, edit = use commit, but stop for amending
#s, squach = user commit, but meld into previous commit
#
step4: 这里是要修改命令
所以要将pick 58dd00b The third commit 这一行中的 pick 改为 reword,即
reword 58dd00b The third commit
pick r8utjm9 The fourth commit!!!
#Commands:
#p, pick = use commit
#r, reword = use commit, but edit the commit message
#e, edit = use commit, but stop for amending
#s, squach = user commit, but meld into previous commit
#
保存退出后会跳进来另一个页面,显示的内容为
The third commit
step5: 接下来就是修改message
在原来的 The third commit后面加上 !!! , 然后继续保存退出
step6: 如果显示如下信息,则表明修改成功
Successfully rebased and updated refs/heads/master
step7:再次用 git log,可以看到commit message信息已经被成功修改了
git log -3 oneline
显示如下:
r8utjm9 The fourth commit!!!
58dd00b The third commit!!!
5t889cc The second commit!!!
step1: 先通过git log来查看要合并的commitID并且找到它的父亲的commitID
git log -5 oneline
显示如下:
37ook07 The fifth commit!!!
r8utjm9 The fourth commit!!!
58dd00b The third commit!!!
5t889cc The second commit!!!
c5l333n The first commit!!!
step2: 想将下面两条连续的commit整理为一个commit
r8utjm9 The fourth commit!!!
58dd00b The third commit!!!
step3: git rebase -i 后面加上commitID
git rebase -i 5t889cc
序列号为要被合并的最老的commit的前一次,即它的父亲
输入上面命令后显示的文件内容如下
pick 37ook07 The fifth commit!!!
pick r8utjm9 The fourth commit!!!
pick 58dd00b The third commit!!!
#Commands:
#p, pick = use commit
#r, reword = use commit, but edit the commit message
#e, edit = use commit, but stop for amending
#s, squach = user commit, but meld into previous commit
#
step4: 这里是要修改命令
pick是默认的, squach是合并
所以要将以下这两行中的 pick 改为 squach
pick r8utjm9 The fourth commit!!!
pick 58dd00b The third commit!!!
squach r8utjm9 The fourth commit!!!
squach 58dd00b The third commit!!!
保存退出后会跳进来另一个页面,显示的内容为
#This is a comobination of 2 commits.
#This is the 1st commit message:
The fourth commit!!!
#This is the commit message #2:
The third commit!!!
step5: 接下来就是添加注释,表明这是被合并的commit
加一条注释
#This is a comobination of 2 commits.
Create a complete commit lalalala
#This is the 1st commit message:
The fourth commit!!!
#This is the commit message #2:
The third commit!!!
然后继续保存退出
step6: 如果显示如下信息,则表明修改成功
Successfully rebased and updated refs/heads/master
step7: 用 git log再次查看日志
就可以看到那两条commit已经被合并了,并产生了新的commitID
同时被合并后的那一条没有变化的commit的CommitID也已经被改变了(因为存在依赖)
git log -5 oneline
显示如下:
88hhwfo The fifth commit!!!
f8fhduh Create a complete commit lalalala
5t889cc The second commit!!!
c5l333n The first commit!!!
step1: 先通过git log来查看要合并的commitID并且找到它的父亲的commitID
git log -4 oneline
显示如下:
88hhwfo The fifth commit!!!
f8fhduh Create a complete commit lalalala
5t889cc The second commit!!!
c5l333n The first commit!!!
step2: 想将倒数第四条,倒数第三条和倒数第一条commit整理为一个commit
88hhwfo The fifth commit!!!
5t889cc The second commit!!!
c5l333n The first commit!!!
step3: git rebase -i 后面加上commitID
git rebase -i c5l333n
序列号为要被合并的最老的commit的前一次,即它的父亲,
但是我们这里要合并的最老的commit就是最早的commit,所以它没有父亲,就直接写它的commitID
输入上面命令后显示的文件内容如下
pick 88hhwfo The fifth commit!!!
pick f8fhduh Create a complete commit lalalala
pick 5t889cc The second commit!!!
#Commands:
#p, pick = use commit
#r, reword = use commit, but edit the commit message
#e, edit = use commit, but stop for amending
#s, squach = user commit, but meld into previous commit
#
step4: 这里是要修改命令
原来的
pick 88hhwfo The fifth commit!!!
pick f8fhduh Create a complete commit lalalala
pick 5t889cc The second commit!!!
改为
squach 88hhwfo The fifth commit!!!
squach 5t889cc The second commit!!!
squach c5l333n The first commit!!!
pick f8fhduh Create a complete commit lalalala
保存退出后页面显示了一些提示信息让我们查看
step5: 此时可以用 git status 来查看下当前的状态
我们发现信息不连续,并提示我们用 以下命令解决
git rebase --continue
step6: git rebase --continue
会跳进来另一个页面,显示的内容为
#This is a comobination of 3 commits.
#This is the 1st commit message:
The fourth commit!!!
#This is the commit message #2:
The second commit!!!
#This is the commit message #3:
The first commit!!!
step5: 接下来就是添加注释,表明这是被合并的commit
加一条注释
#This is a comobination of 3 commits.
Create a complete commit hhhhhhhhhhhh
#This is the 1st commit message:
The fourth commit!!!
#This is the commit message #2:
The second commit!!!
#This is the commit message #3:
The first commit!!!
然后继续保存退出
step6: 如果显示如下信息,则表明修改成功
Successfully rebased and updated refs/heads/master
step7: 用 git log 查看日志,就可以看到那三条commit已经被合并了,并产生了新的commitID
git log -4 oneline
显示如下:
e33fjii Create a complete commit lalalala
ur83h43 Create a complete commit hhhhhhhhhhhh
git diff 就是我们本地正在开发的但未提交到暂存区文件和之前已经提交到暂存区里的文件的对比;
git diff --cached 最后一次提交到版本库环境中文件和暂存区中文件的修改对比;
git diff head 就是已经提交到版本库环境中的文件和未提交到版本库环境中文件的所有修改对比;
git diff 就是我们本地正在开发的但未提交到暂存区文件和之前已经提交到暂存区里的文件的对比;
git diff
git diff --cached
git diff head
git diff BranchName1 BranchName2 对比指定的分支的最新的commit之间的所有文件的差异
git diff BranchName1 BranchName2 -- FileName 对比指定的分支的最新的commit之间的指定的FileName文件的差异
git diff BranchName1_CommitID BranchName2_CommitID 对比指定的分支的指定的的commit之间的所有文件的差异
暂存区的文件不成熟,不打算生成commit
use “git reset HEAD …” to unstage
git reset HEAD
已经做了git add FileName 操作, 然后对FileName又做了更改
打算抛弃工作区的修改, 采纳已经提交到暂存区的内容
(工作区的内容不及已经提交到暂存区的内容)
use “git checkout – …” to discard changes in working directory
git checkout -- FileName
use “git reset HEAD …” to unstage
git reset HEAD -- FileName
git reset HEAD -- FileName1 FileName2
git reset --hard CommitID
当你正在开发环境时,有一个任务已经做了一些提交到暂存区的操作,有一些文件还在修改过程
又突然来了更紧急的任务需要在自己的开发环境下处理
step1:先把原来的有修改过的内容存到不影响紧急任务的环境中
git stash 暂存工作区修改的内容
git stash
会显示
Saved working directory and index state WIP on temp: 9we3d0 Add commit for xxx
step2: 查询工作区所有stash的列表
git stash list 查询stash的列表
git stash list
显示如下,说明此时只有一个stash,只有一个暂存
stash@{0}: WIP on master: 9we3d0 Add commit for xxx
如果用 git stash list显示如下,说明此时有3个暂存
stash@{0}: WIP on master: 9we3d0 xxx1
stash@{1}: WIP on master: 2we3d0 xxx2
stash@{2}: WIP on master: 4we3d0 xxx3
step3:查看当前工作区状态
git status 查看当前工作区是否干净
git status
当显示下面两行,就可以得知当前的工作区是干净的,就可以做紧急任务了
On branch master
nothing to commit, working tree clean
step4:继续在原来没工作完成的环境下继续工作
git stash pop 恢复暂存的工作内容,获取到的是最近一次stash进去的内容
如果stash两次或者多次,那么恢复的是最新一次stash进去的内容
git stash pop
git diff 查看是否恢复到原来的工作环境中了
如果想恢复stash@{1},
git stash apply stash@{1}
清空stash
git stash clear
不想让本地仓库的所有文件都上传到远程仓库,我们可以通过.gitignore文件来指定不需要被git管理的文件
.gitignore 是使用通配符来指定哪些文件不需要被git管理的
*.so 所有以so结尾的文件
*.a 所有以 a结尾的文件
Hello 文件名为Hello的文件
doc/ doc目录下的所有文件
本地--------push-------> 远端
本地<-----fetch--------- 远端
本地协议1 哑协议 【语法: /Path/to/Repository.git】
本地协议2 智能协议 【语法 file:///Path/to/Repository.git】
直观区别 哑协议传输进度不可见,智能协议传输进度可见
传输速度 智能协议速度更快
git clone --bare
用于在不需要完整的工作树的情况下把整个仓库克隆到本地--bare选项可以节省磁盘空间
,同时可以加速克隆操作,特别是在仓库比较大的情况下使用--bare选项克隆的仓库通常用于服务器端的管理和备份
,而不是作为本地开发和修改的工作目录使用OrigRepository 是原始仓库的地址,bare-repository.git 是裸仓库的名称
git clone --bare <OrigRepository> <bare-repository.git>
1) 需要被备份的仓库
/Users/GitLearnRepo
2) 要备份到这个目录
/home/Backup2023
3) 哑协议备份
git clone --bare /Users/GitLearnRepo/.git /home/Backup2023/ya_Protocol.git
4) 智能协议备份
git clone --bare file:///Users/GitLearnRepo/.git /home/Backup2023/zhineng_Protocol.git
git remote add <shortname> <url>
shortname 是简写, 就可以使用简写来代替整个url
git remote add SName2023 https://github.com/path2/AGitRepo
git remote add zhineng_Protocol file:///home/Backup2023/zhineng_Protocol.git
git push zhineng_Protocol
有账号后就可以 将自己的项目做备份, 查看github上的项目
https://github.com/
需要输入用户名,邮箱号,密码
https://help.github.com
选择
Adding a new SSH key to your GitHub account
step1: 检查是否已经存在公私钥
cd ~/.ssh
ls -al
如果存在 id_rsa 和 id_rsa.pub 则说明当前存在公私钥。
step2: 创建公私钥
ssh-keygen -t rsa -b 4096 -C "[email protected]"
然后一路按回车, 直到结束
将公钥复制粘贴到 GitHub上
输入仓库名
仓库类型分为 public 和 private
step1: 复制github的地址
在GitHub中找到要同步的仓库
选择
clone or download
就可以复制github的地址
目前为
[email protected]:xxx/git_repo.git
step2: 用git remote 来同步
git remote add github20230612 [email protected]:xxx/git_repo.git
此时就可以用 名为 github20230612 的简写来代表 [email protected]:xxx/git_repo.git
step3: 检查是否同步成功
git remote -v
显示下面则说明成功
github20230612 [email protected]:xxx/git_repo.git (fetch)
github20230612 [email protected]:xxx/git_repo.git (push)
step4: 本地和远端同步
此时就可以从本地给远端push,或从远端fetch到本地
git push github20230612 --all
将本地仓库push到远端
此时却出现了错误
To [email protected]:xxx/git_repo.git
![rejected] master -> master (fetch first)
error: failed to push some refs to '[email protected]:xxx/git_repo.git'
hint: Updates were rejected because the remote contains work that you do not have locally.
hint: This is usually caused by another repository pushing to the same ref.
hint: You may want to first integrate the remote changes (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
错误:无法将某些引用推送到'[email protected]:xxx/git_repo.git'
提示:更新被拒绝,因为远程包含您在本地没有的工作。
提示:在再次推送之前,您可能需要先集成远程更改(例如“git pull…”)。
这个错误说明 远端存在本地仓库没有的文件, 所以远端拒绝了本次同步
这时我们就需要先把远端分支拉下来,本地拥有了和远端的文件, 就可以再次用push做同步。
1, 用 git fetch 把远端拉下来
git fetch github20230612 master
2, av 是检查远端和本地所有的分支
git branch -av
3, 切换到出错的master分支
git checkout master
4, 将远端和本地代码合并
git merge github20230612/master
5, 出现如下错误
fatal: refusing to merge unrelated historied
6, 加上merge的参数来解决
git merge --allow-unrelated-historied github20230612/master
就成功了
Git 查看某个文件的提交历史
git log ${FileName}