文章目录
一 连接GIT到Github
1、GIT下载
GIT下载地址,下载后打开Git Bash
2、创建SSH Key并添加
ssh-keygen -t rsa -C 你的邮箱 #执行后全部回车即可
- 在
C:\Users\Administrator\.ssh
中会生成公钥id_rsa.pub
和私钥id_rsa
复制公钥内容,并添加到Github中:Add new SSH keys
3、连接Github
git remote add origin git@github.com:用户名/仓库名.git
---相关指令---
git remote #查看当前远程连接
git remote -v #查看是否连接
git remote rm [name] #删除指定远程连接
二 基本配置
Git自带一个git config
工具来帮助我们设置用来控制Git的外观和行为的变量
git config --global [配置项] [配置值] #配置变量
git config --list #列出所有配置
git config [配置项] #列出某一项配置
--global
选项使用后配置的信息一直保存,不用该选项,则可以指定某个GIT有不同的用户名和邮件地址
上述的自定义的配置文件通常都存放在.git/config
中,当前用户的Git配置文件在隐藏文件.gitconfig
中
cat .git/config
cat .gitconfig
1、用户名和邮件
Git每次提交都会使用用户名和邮件,它会写入到每一次提交中
git config --global user.name "用户名"
git config --global user.email 邮箱
2、显示颜色
git config --global color.ui true #打开显示颜色选项,这样显示一些状态信息更直观
3、忽略上传
有一些文件必须放在Git目录,如数据库密码、代码编译中间文件,这些都没有必要上传。此时可以创建一个.gitignore
文件,并添加忽略上传的文件名。例:
# Windows: windows产生的垃圾文件
Thumbs.db
ehthumbs.db
Desktop.ini
# Python: 编译产生的文件
*.py[cod]
*.so
*.egg
*.egg-info
dist
build
# My configurations:自己定义的不上传的文件
db.ini
deploy_key_rsa
- 问题:比如想排除
.
开头的文件,但此时把.gitingore
也给排除了,解决方法:
git add -f [文件名] #可以每次手动添加 -f表示强制添加
---检查某个文件是否被忽略---
git check-ignore -v [文件名]
但是每次都要写一遍强制添加很麻烦,故可以在.gitignore
中这样写:
# 排除所有.开头的隐藏文件:
.*
# 不排除.gitignore
!.gitignore
4、别名
有些命令太长了,为了简化输入,可以为一些命令配置别名
git config --global alias.[自定义缩写] [原命令]
---例---
git config --global alias.st status #此时git status,输入git st即可
git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.br branch
git config --global alias.last 'log -1' #git last则显示最后一次提交
三 基本使用
1、初始化仓库
git init
:在已存在目录中创建一个版本库
mkdir learning-git #创建目录
cd learning-git #进入目录
pwd #查看当前目录
git init #把当前目录变成Git可以管理的仓库
ls -ah #可以看到目录下有一个.git目录,它是用来跟踪管理版本库的
2、克隆仓库
git clone
:克隆该仓库上的所有数据
git clone <url>
3、添加文件到暂存区(stage)并提交
- 工作区:用户本地的目录
- 暂存区(stage):用户通过
git add
添加的文件。
用户git commit
就是把暂存区的内容提交到当前分支。
git add [filename] [filename] #可以添加多个文件到暂存区
git commit -m "说明" #提交到本地分支,-m为本次提交的说明
git restore --staged <file> #保存到暂存区的文件又被修改了,用此命令更新
---git log---
git log #查看全部的commit记录
git log --pretty=oneline #一行显示
git log --graph --pretty=oneline --abbrev-commit #查看提交图
4、远程操作
(1)推送/创建分支
假设本地有<branch>
分支,通过该命令将本地的<branch>
分支上传到服务器,若服务器中没有该分支则创建
git push <remote> <branch>
(2)拉取远程分支
git pull <remote> <branch>
git push/pull
加上-u
选项,则第一次需要写后面的origin <branch>
,后面就不需要再写了
(3)关联本地分支和远程分支
git branch --set-upstream-to=<remote>/<remote branch> <local branch>
(4)删除远程分支
git push origin :<remote branch>
(5)查看本地/远程分支
git branch #查看本地分支
git branch -a #查看本地和远程分支
(6)合并远程分支
有时不小心提交了一次要删掉,或者多个小功能提交了一次,仅仅是更改了很少的地方,造成版本回溯的不方便。
git switch <branch> #切换到待合并commit所在的分支
git rebase -i HEAD~3 #查看最近三次的提交(假设要合并最近三次的提交)
此时会打开一个提交日志,前三行则对应最近三次的提交,将第一行保留,后两行前面的pick
改为s
,表示将最新两次的commit中的改变合并到之前的commit中。
5、版本管理
(1)回退
HEAD
表示当前版本,HEAD^
表示上一个版本,HEAD^^
表示上上个版本- 上100个版本:
HEAD~100
- 上100个版本:
git reset --hard HEAD^ #回退到上一个版本
现在又想切换到最新版本,但是找不到commid id,可以查看记录通过commid id切换
git reflog #记录每一条命令,以此查看最新版本的commit id
git reset --hard [commid id] #回退
(2)其它
①有时提交完了才发现有的文件没有add或者提交信息写错了,在添加完文件之后,可以在commit
后加上--amend
选项,这样就不会再多创建一个commit了
git commit --amend
②取消暂存区中的某个文件
git reset HEAD <filename>
git status #查看改变
git status
:查看工作目录中有哪些文件还没有放进暂存区、暂存区中有哪些内容还没有提交到仓库、暂存区中被修改的文件git diff [commid id]
:git status
只知道哪个文件被修改了,该命令可显示暂存区某个文件的具体修改git diff [commid id1] [commid id2]
:比较两个提交的差异
③将某个文件回退为上一次提交的版本
git checkout -- readme.txt #用最近提交的版本覆盖它:版本库中存在,本地不存在
6、删除文件
一般情况下,直接在文件管理器中或者用rm
命令删掉,此时git status
可以看得到删除了。
# 添加文件并提交
git add test.txt
git commit -m "add test.txt"
# 删除版本库中的文件
git rm test.txt
git commit -m "remove test.txt"
# 删错了还原:版本库中存在,本地不存在该文件
git checkout -- test.txt
四 分支管理
4.1 理论
Git保存的不是文件的变化或差异,而是一系列不同时刻的快照。
假设有三个要被暂存和提交的文件,暂存操作会为每个文件计算校验和,然后会把当前版本的文件快照保存到Git仓库中,最终将校验和加入到暂存区并等待提交。
- Git使用blob对象来保存文件快照
当使用git commit
进行提交操作时,会先计算每一个子目录的校验和,这些校验和保存为树对象。随后,Git 便会创建一个提交对象, 它除了包含上面提到的那些信息外,还包含指向这个树对象(项目根目录)的指针。 如此一来,Git 就可以在需要的时候重现此次保存的快照。
Git仓库对象变化例子
现在Git仓库中有5个对象:
- 3个blob对象:保存文件快照
- 1个树对象:记录目录结构和blob对象索引
- 1个提交对象:包含指向树对象的指针和所有提交信息
做些修改后再次提交,那么这次产生的提交对象会包含一个指向上次提交对象(父对象)的指针。
Git分支是指向提交对象的可变指针,默认分支名字是master
。 多次提交操作后,就有一个指向最后那个提交对象的master
分支。master
分支会在每次提交时自动向前移动。
Git会把每次提交串成一条时间线,这条时间线就是一个分支,每个仓库都有一个主分支master
。
- Head指向的是当前分支的指针,而不是当前分支指向的commit的指针
- 每次提交
master
分支都会向前移动一步
创建分支
当我们创键新的分支dev
时,其指向与master
相同的提交,再将HEAD指向dev
,表示当前分支在dev
上。
现在对工作区的修改和提交就是针对dev
分支了,新提交一次后,dev
指针往前移动一步,而master
指针不变:
现在想把dev
合并到master
上,最简单的就是把master
指向dev
的当前提交。合并完分支后,甚至可以删除dev分支。删除dev
分支就是把dev
指针给删掉,就剩下了一条master
分支:
- 上图为
fast forward
模式,分支合并时默认为该模式。若不在此模式下,合并时会创建一个新的commit。
4.2 相关指令
1、创建并切换分支
git checkout -b dev #表示创建并切换
# 等价于下面两行代码
git branch dev
git checkout dev
仅切换分支:
git checkout dev
2、查看分支
git branch #查看所有分支,当前分支前面有*号标注
3、合并并删除分支
git checkout master #切换到分支master
git merge dev #合并指定分支dev到master
git branch -d dev #删除本地dev分支,要先切换到master分支
git push origin --delete dev #删除远程分支
git branch #查看分支
- 把dev分支合并到master上,合并后
master
分支的指针指向最新合并的commit
合并时如果master分支没有新增commit,则默认会使用Fast forward
模式,但这种模式下,删除分支后会丢掉分支信息。可以使用--no-ff
,禁用该模式,在merge时就会生成一个新的commit,就能看出分支信息。
git switch master #切换回master分支
git merge --no-ff -m "merge with no-ff" dev #这样合并会创建新的commit,所以-m添加描述
git log --graph --pretty=oneline --abbrev-commit #查看分支历史
- 不使用
Fast forward
模式例:
4、Git checkout
git checkout <branch>
:切换分支git checkout -- <file>
:撤销修改,回溯
一个checkout命令有两个功能有点让人迷惑,用switch会更好理解一些:
git switch -c dev #创建并切换到新dev分支
git switch master #切换到已有的master分支
5、注意事项
master
分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活- 干活都在
dev
分支上,比如到1.0版本发布时,再把dev
分支合并到master
上,并在master
分支发布1.0版本dev
即develop的缩写,表示开发分支。
- 每个人都在
dev
分支上干活,每个人都有自己的分支,时不时地往dev
分支上合并就可以了
五 标签管理
发布一个版本时,通常先在版本库中打一个标签(tag),这样就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。标签其实就是指向某个commit的指针。
- commit号如“6a5819e…”,而标签可以自己定义,如“v1.2”。
- tag和commit对应,如果一个commit出现在多个分支上,则这些分支都可以看到这个tag
git branch #查看分支
git checkout master #切换分支
git tag v1.0 #打标签
git tag #查看所有标签,按字母排序
git show tagname #根据标签名查看具体信息
git tag v0.9 fb8b190 #标签默认打在最新的commit上,可指定commit id加标签
git tag -a v0.1 -m "version 0.1 released" 187f963 #带有说明的标签 -a指定标签 -m说明