您现在的位置是:首页 >学无止境 >Git GitHub网站首页学无止境
Git GitHub
Git
一、Git 基础
01- 了解Git
1、没有Git
用目录拷贝区分不同版本 成员沟通成本高,代码集成效率低
2、集中式VCS
集中的版本管理服务器 客户端要一直和服务器相连
3、分布式VCS
客户端脱离服务端照样可以管理版本
4、Git
版本控制系统
最优的存储能力,非凡的性能, 开源的,容易备份,支持离线操作,容易定制工作流程
5、GitHub、GitLab为Git做服务
GitHub 全球最大的开源社区,优秀的开源项目,来存储代码
GitLab 有社区版本
02- 安装git
https://git-scm.com/book/zh/v2/起步-安装-Git
03- 使用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 wang@xxx.com 设置全局的用户名邮箱
git config --local user.email zhao@xxx.com 设置项目级的用户名邮箱
git config user.name 查看当前用户名
cat ~/.gitconfig 显示全局用户名
cat .git/config 显示特定项目级的用户名(在特定的git项目下)
当需要在别人的机器上建立自己的git项目,并且想以自己的名字和邮件提交时,就可以设置特定项目级的用户名
用list来查看所设置的所有内容
git config --global --list
git config --local --list
04- 创建第一个仓库并配置local用户信息
建Git仓库
1、把已有的项目代码纳入Git管理
项目名为 git_learning_directory
cd xxxPATHxxx
git init git_learning_directory
就可以做git add, git commit操作了
05- 重命名或者删除已经被git管理的文件
05.1 重命名已经被git管理的文件 两种方法
- 麻烦,不推荐
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'
05.2 删除已经被git管理的文件
git rm FileName
git status
git commit -m 'remove FileName'
06- gitk
通过图形界面工具来查看版本历史
gitk需要安装
07- .git目录
.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
07.1 HEAD 显示仓库当前工作的分支
cat HEAD
ref: refs/heads/CurrentBranchName
如果切换了分支,则HEAD文件内容会被改变
07.2 config 跟本地相关的配置信息
cat config
[user]
name = zhao
email = zhao@xxx.com
cat config显示的内容可通过如下方法设置及查看
git config --local user.name
git config user.name
07.3 refs
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
07.3.1 heads
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
07.3.2 remotes
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
07.3.3 tags
显示tag信息
08- commit、tree和blob三个对象的关系
一个commit,说明有一次变更,包含 tree(相当于文件夹)、parent、author和committer。
一个commit对应一棵树tree,代表当前commit对应仓库的所有文件夹的快照
一个tree包含tree和blob
一个blob指的就是具体的文件内容
在git中,blob与文件名无关,只与文件内容有关,即文件内容相同,在git中是同一个blob。
二、使用Git
09- 修改commit的message
09.1 修改最新commit的message
输入该命令后,就可以在打开的文件中修改,之后保存退出即可。
git commit --amend
09.2 修改老旧commit的message
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 <commit> = use commit
#r, reword <commit> = use commit, but edit the commit message
#e, edit <commit> = use commit, but stop for amending
#s, squach <commit> = 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 <commit> = use commit
#r, reword <commit> = use commit, but edit the commit message
#e, edit <commit> = use commit, but stop for amending
#s, squach <commit> = 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!!!
10- 将多个commit整理为一个commit来提交
10.1 将已经提交的连续的多个commit整理为一个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 <commit> = use commit
#r, reword <commit> = use commit, but edit the commit message
#e, edit <commit> = use commit, but stop for amending
#s, squach <commit> = 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!!!
10.2 将已经提交的间隔的的几个commit整理为一个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 <commit> = use commit
#r, reword <commit> = use commit, but edit the commit message
#e, edit <commit> = use commit, but stop for amending
#s, squach <commit> = user commit, but meld into previous commit
#
step4: 这里是要修改命令
- pick是默认的, squach是合并,所以要将需要改变的行中的 pick 改为 squach
- 我们发现显示的文件里面并没有要合并的最老的commit信息,所以我们要加进来最老的commit的信息
- 并且把要合并的commit的信息放在上面,构成上下行的关系
原来的
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
11- 比较同一个分支下的文件差异 git [ diff / --cached / diff head ]
- 三个环境, 本地正在编辑的开发环境,暂时存放代码的暂存区,提交的版本库环境
- 在本地环境修改后, git add FileName, 文件就从本地被添加到暂存区了
- 暂存区的文件,git commit -m ‘Description,xxx’, 暂存区的文件就被添加到版本库环境了
git diff 就是我们本地正在开发的但未提交到暂存区文件和之前已经提交到暂存区里的文件的对比;
git diff --cached 最后一次提交到版本库环境中文件和暂存区中文件的修改对比;
git diff head 就是已经提交到版本库环境中的文件和未提交到版本库环境中文件的所有修改对比;
11.1 git diff 比较工作区和暂存区所含文件的差异
git diff 就是我们本地正在开发的但未提交到暂存区文件和之前已经提交到暂存区里的文件的对比;
git diff
11.2 git diff --cached 比较暂存区和HEAD所含文件的差异
git diff --cached
11.3 git diff head 已经提交到版本库环境中的文件和未提交到版本库环境中文件的所有修改对比
git diff head
12- 比较不同分支提交的指定文件的差异
git diff BranchName1 BranchName2 对比指定的分支的最新的commit之间的所有文件的差异
git diff BranchName1 BranchName2 -- FileName 对比指定的分支的最新的commit之间的指定的FileName文件的差异
git diff BranchName1_CommitID BranchName2_CommitID 对比指定的分支的指定的的commit之间的所有文件的差异
13- 文件恢复
13.1 reset 暂存区恢复成和HEAD一样
暂存区的文件不成熟,不打算生成commit
use “git reset HEAD …” to unstage
git reset HEAD
13.2 checkout 工作区恢复成和暂存区一样
已经做了git add FileName 操作, 然后对FileName又做了更改
打算抛弃工作区的修改, 采纳已经提交到暂存区的内容
(工作区的内容不及已经提交到暂存区的内容)
use “git checkout – …” to discard changes in working directory
git checkout -- FileName
13.3 reset 取消暂存区部分文件的更改
use “git reset HEAD …” to unstage
git reset HEAD -- FileName
git reset HEAD -- FileName1 FileName2
13.4 消除最近几次的提交
git reset --hard CommitID
14- 开发中临时加塞了紧急任务如何处理
当你正在开发环境时,有一个任务已经做了一些提交到暂存区的操作,有一些文件还在修改过程
又突然来了更紧急的任务需要在自己的开发环境下处理
14.1 步骤一 先把自己原来的一些修改先保存起来,优先处理紧急的任务
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
14.2 步骤二 在紧急的任务完成提交后,把环境恢复到上个任务正在做的环境中
step4:继续在原来没工作完成的环境下继续工作
git stash pop 恢复暂存的工作内容,获取到的是最近一次stash进去的内容
如果stash两次或者多次,那么恢复的是最新一次stash进去的内容
git stash pop
git diff 查看是否恢复到原来的工作环境中了
如果想恢复stash@{1},
git stash apply stash@{1}
清空stash
git stash clear
15- .gitignore文件
不想让本地仓库的所有文件都上传到远程仓库,我们可以通过.gitignore文件来指定不需要被git管理的文件
.gitignore 是使用通配符来指定哪些文件不需要被git管理的
*.so 所有以so结尾的文件
*.a 所有以 a结尾的文件
Hello 文件名为Hello的文件
doc/ doc目录下的所有文件
16- 将git仓库备份到本地
本地--------push-------> 远端
本地<-----fetch--------- 远端
16.1 在本地环境下有两种备份的协议
本地协议1 哑协议 【语法: /Path/to/Repository.git】
本地协议2 智能协议 【语法 file:///Path/to/Repository.git】
直观区别 哑协议传输进度不可见,智能协议传输进度可见
传输速度 智能协议速度更快
16.2 备份命令 git clone --bare 介绍
git clone --bare
用于在不需要完整的工作树的情况下把整个仓库克隆到本地- –bare表示裸仓库,它只包含.git文件夹,而没有工作目录。
- 相比于常规的克隆操作,
--bare选项可以节省磁盘空间
,同时可以加速克隆操作,特别是在仓库比较大的情况下 使用--bare选项克隆的仓库通常用于服务器端的管理和备份
,而不是作为本地开发和修改的工作目录使用- 当需要对仓库进行修改时,可以从–bare仓库克隆一个有工作目录的版本进行修改
16.3 使用git clone --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
16.3- 添加远程仓库到本地
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
三、Git与GitHub的简单同步
17- 注册一个GitHub账号
有账号后就可以 将自己的项目做备份, 查看github上的项目
https://github.com/
需要输入用户名,邮箱号,密码
18- 配置公私钥
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 "xxx@xx.co"
然后一路按回车, 直到结束
将公钥复制粘贴到 GitHub上
19- 在GitHub上创建个人仓库
输入仓库名
仓库类型分为 public 和 private
20- 将本地仓库同步到GitHub
step1: 复制github的地址
在GitHub中找到要同步的仓库
选择
clone or download
就可以复制github的地址
目前为
git@github.com:xxx/git_repo.git
**step2: 用git remote 来同步**
git remote add github20230612 git@github.com:xxx/git_repo.git
此时就可以用 名为 github20230612 的简写来代表 git@github.com:xxx/git_repo.git
step3: 检查是否同步成功
git remote -v
显示下面则说明成功
github20230612 git@github.com:xxx/git_repo.git (fetch)
github20230612 git@github.com:xxx/git_repo.git (push)
step4: 本地和远端同步
此时就可以从本地给远端push,或从远端fetch到本地
git push github20230612 --all
将本地仓库push到远端
此时却出现了错误
To git@github.com:xxx/git_repo.git
![rejected] master -> master (fetch first)
error: failed to push some refs to 'git@github.com: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.
错误:无法将某些引用推送到'git@github.com:xxx/git_repo.git'
提示:更新被拒绝,因为远程包含您在本地没有的工作。
提示:在再次推送之前,您可能需要先集成远程更改(例如“git pull…”)。
这个错误说明 远端存在本地仓库没有的文件, 所以远端拒绝了本次同步
这时我们就需要先把远端分支拉下来,本地拥有了和远端的文件, 就可以再次用push做同步。
git fetch github20230612 master
git branch -av
git checkout master
git merge github20230612/master
出现
fatal: refusing to merge unrelated historied
git merge --allow-unrelated-historied github20230612/master
就成功了
Git查看某个指定文件的历史提交记录list
一、查看某个文件的提交历史
1.1 git log ${FileName}
查看某个文件的commit记录