一、Git
1. Git的常用操作
1.1 本地库初始化
- 进入自己创建的git仓库目录下,使用命令
git init
1 | hxhaaj@DESKTOP-CP80SC0 MINGW64 /d/code/GitSpace/testGit (master) |
- 此时就会提示在该目录下初始化了一个空的Git仓库
Initialized empty Git repository in D:/code/GitSpace/testGit/.git/
使用命令
ll -la
显示所有含有隐藏目录.git
查看
.git/
目录下的目录结构:1
2
3
4
5
6
7
8
9$ ll
total 7
-rw-r--r-- 1 hxhaaj 197121 130 6月 22 17:12 config
-rw-r--r-- 1 hxhaaj 197121 73 6月 22 17:12 description
-rw-r--r-- 1 hxhaaj 197121 23 6月 22 17:12 HEAD
drwxr-xr-x 1 hxhaaj 197121 0 6月 22 17:12 hooks/
drwxr-xr-x 1 hxhaaj 197121 0 6月 22 17:12 info/
drwxr-xr-x 1 hxhaaj 197121 0 6月 22 17:12 objects/
drwxr-xr-x 1 hxhaaj 197121 0 6月 22 17:12 refs/
1.2 设置签名
1.2.1 项目级/仓库级别签名
仅仅在当前本地库范围内有效
命令:
git config user.name xxx
设置项目级用户名称命令:
git config user.email xxx
设置项目级用户email信息保存在
.git/config
文件中
1.2.2 系统用户级签名
登录当前操作系统的用户范围
命令:
git config --global user.name xxx
设置系统用户级用户名称命令:
git config --global user.email xxx
设置系统用户级用户email签名信息保存在 系统用户目录下的
~/.gitconfig
文件中1
2
3
4$ cat .gitconfig
[user]
name = hxhaaj_glb
email = hxhaaj_glb@163.com
1.2.3 级别优先级
项目级别
优先于系统用户级别,二者都有时采用项目级别
的签名- 如果只有系统用户级别的签名,就以系统用户级别的签名为准
- 二者都没有不允许这种情况
1.3 基本操作
1.3.1 状态查看操作
命令: git status
查看工作区、暂存区状态1
2
3
4
5
6
7
8
9
10
11$ git status
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
t1.txt
nothing added to commit but untracked files present (use "git add" to track)
1.3.2 添加操作
git add [file name]
将工作区的新建或者修改
后的文件添加到暂存区
1
$ git add t1.txt
执行后,查看状态:1
2
3
4
5
6
7
8
9$ git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: t1.txt
1.3.3 暂存区删除操作
git rm --cache [filename]
将暂存区
中的文件,移除暂存区,避免误添加操作1
2$ git rm --cached t1.txt
rm 't1.txt'
删除后,回到原状态:查看状态:1
2
3
4
5
6
7
8
9
10
11$ git status
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
t1.txt
nothing added to commit but untracked files present (use "git add" to track)
1.3.4 提交操作
命令: git commit
将暂存区的内容提交到本地库
- 提交并直接写入本次提交提示信息
git commit -m "xxx提交提示信息" [文件名]
1 | $ git commit -m "new file t1 and insert some .." t1.txt |
1.3.5 查看日志
git log
最完整的形式1
2
3
4
5
6
7
8
9
10
11
12$ git log
commit b4b7b3ecb73218f06a882363ea8982e78aea59b6 (HEAD -> master)
Author: hxhaaj <hxhaaj@163.com>
Date: Fri Jun 22 22:33:57 2018 +0800
new file t1 and insert some ..
commit 55afec262bc7db58f8307f788dc57f3118e0d3d1
Author: hxhaaj <hxhaaj@163.com>
Date: Fri Jun 22 22:28:49 2018 +0800
new t1`
git log --pretty=oneline
以一条信息一行的简洁状态显示日志1
2
3$ git log --pretty=oneline
b4b7b3ecb73218f06a882363ea8982e78aea59b6 (HEAD -> master) new file t1 and insert some ..
55afec262bc7db58f8307f788dc57f3118e0d3d1 new t1`
git log --oneline
哈希值简短显示的简洁状态 更简洁 只显示过去版本1
2
3$ git log --oneline
b4b7b3e (HEAD -> master) new file t1 and insert some ..
55afec2 new t1`
git reflog
增加了头指针移动次数信息 HEAD@{x} x为移动到当前版本需要的次数 常用,新老版本都能全部显示1
2
3$ git reflog
b4b7b3e (HEAD -> master) HEAD@{0}: commit: new file t1 and insert some ..
55afec2 HEAD@{1}: commit (initial): new t1`
多屏显示控制方式:
空格向下翻页
b向上翻页
q退出
1.3.6 前进后退
本质:根据最新版本为HEAD指针,即HEAD指针到旧版本所需要移动的次数,如下HEAD@{0}为最新版本
1
2b4b7b3e (HEAD -> master) HEAD@{0}: commit: new file t1 and insert some ..
55afec2 HEAD@{1}: commit (initial): new t1`基于索引值操作(推荐)
git reset --hard [局部索引值(55afec2)]
回到或者前进到索引值代表的那个版本
1 | $ git reset --hard 55afec2 |
此时回到了55afec2这个版本,再使用 git reflog
查看日志1
2
3
4$ git reflog
55afec2 (HEAD -> master) HEAD@{0}: reset: moving to 55afec2
b4b7b3e HEAD@{1}: commit: new file t1 and insert some ..
55afec2 (HEAD -> master) HEAD@{2}: commit (initial): new t1`
使用 ^ 符号形式 只能后退
git reset --hard HEAD[^]
一个^符号,退一个版本,n个^符号,退n个版本
1
2$ git reset --hard HEAD^
HEAD is now at 55afec2 new t1`使用 ~ 符号形式
git reset --hard HEAD~n
n代表后退多少步,同样也只能后退1.3.7 reset命令的三个参数对比
--soft
参数
仅仅在本地库移动HEAD指针--mixed
参数
在本地库移动HEAD指针,重置暂存区--hard
参数
在本地库移动HEAD指针,重置暂存区,重置工作区
1.3.7 删除文件并找回
- 前提:删除前,文件存在时的状态提交到了本地库。
- 命令:
git reset --hard [指针位置]
删除操作已经提交到本地库:指针位置指向历史记录
删除操作没有提交到本地库:指针位置使用HEAD
1.3.8 比较文件差异
git diff [文件名]
不带参数,将工作区中的文件和暂存区进行比较git diff[本地库中历史版本] [文件名]
将工作区中的文件和本地库历史记录进行比较git diff HEAD t1.txt
git diff HEAD^ t1.txt
不指定文件名,比较多个文件
1.4 分支
1.4.1 分支的好处
- 同时并行推进多个功能开发,提高开发效率
- 各个分支在开发过程中,如果某个分支开发失败,不会对其他分支有任何影响。失败的分支删除重新开始即可。
1.4.2 分支操作
创建分支
git branch [分支名]
查看分支
git branch -v
切换分支
git checkout [分支名]
合并分支
第一步:切换到接受修改的分支(被合并的,增加新内容的分支)上git checkout [被合并分支名]
第二步:执行merge命令git merge [有新内容的分支名]
解决冲突
- 合并后有冲突的分支的表现:
- 解决方式:
- 第一步:编辑文件,删除特殊符号
- 第二步:把文件修改到满意的程序,去掉冲突,保存退出
- 第三步:
git add [文件名]
- 第四步:
git commit -m "日志信息"
- 注意点:此时commit 一定不能带具体文件名
2. Git的基本原理
2.1 哈希
哈希是一系列的加密算法,各个不同的哈希算法虽然加密强度不同,但是有以下几个共同点:
- 不管输入数据的数据量有多大,输入同一个哈希算法,得到加密结果长度固定。
- 哈希算法确定,输入数据确定,输出数据能够保证不变。
- 哈希算法确定,输入数据有变化,输出数据一定有变化,而且通常变化很大
- 哈希算法是不可逆的
- Git底层采用的是SHA-1算法。
- 哈希算法常常被用来验证文件的完整性,确定性。
- Git底层就是根据这种验证机制保证了数据的完整性。
2.2 Git保存版本的机制
2.2.1 集中式版本控制工具的文件管理机制
以文件变更列表的方式存储信息。这类系统将他们保存的信息看做是一组基本文件和每个文件随时间逐步累积的差异。
2.2.2 Git的文件管理机制
Git把数据看做是小型文件系统的
一组快照
。每次提交更新时Git都会对当前的全部文件制作一个快照并保存这个快照的索引
。为了高效,如果文件没有修改
,Git不再重新存储该文件
,而是只保留一个链指向之前存储的文件
。所以Git的工作方式可以称之为快照流
。
2.2.3 Git文件管理机制细节
Git的“提交对象“
提交对象及其父对象所形成的链条
2.3 Git分支管理机制
2.3.1 分支的创建
2.3.1 分支的切换
实质上是指针指向的对象变了,改变指针的指向,快速做到切换。
仅仅移动了指针,切换了版本
此时开始有了分支,都基于f30ab版本
所有操作都是基于链条指针的移动和切换。
3. Git的远程操作
3.1 在本地初始化本地仓库,将文件提交到本地库
3.2 在远程代码托管中心创建好仓库
3.3 在git上给远程仓库地址起个别名
起别名:
git remote add [别名] [仓库地址]
1
$ git remote add git_note https://github.com/hxhaaj/Git_note.git
查看远程仓库信息以及别名:
git remote -v
1
2
3$ git remote -v
git_note https://github.com/hxhaaj/Git_note.git (fetch)
git_note https://github.com/hxhaaj/Git_note.git (push)
3.4 推送到远程库
git push [仓库地址别名] [创建的分支名]
测试后,弹出登陆窗口,登陆后显示提交进度。
1 | $ git push git_note master |
3.5 克隆远程库
git clone [远程库地址]
1 | $ git clone https://github.com/hxhaaj/Git_note.git |
3.7 pull拉取操作
- pull = fetch + merge 即为pull操作是fetch操作和merge操作的组合,仅仅是fetch操作,不改变本地库,merge操作之后改变本地库里的文件
git fetch [远程库地址别名][远程分支名]
1
2
3
4
5
6
7
8$ git fetch git_note master
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 6 (delta 2), reused 3 (delta 1), pack-reused 0
Unpacking objects: 100% (6/6), done.
From https://github.com/hxhaaj/Git_note
* branch master -> FETCH_HEAD
8228eff..aeda745 master -> git_note/mastergit merge [远程库地址别名]/[远程分支名]
1
2
3
4
5$ git merge git_note/master
Updating 8228eff..aeda745
Fast-forward
Git.md | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 64 insertions(+), 15 deletions(-)pull 操作可以直接更新本地库,是fetch和merge的一次性操作
git pull [远程库地址别名] [远程分支名]
3.8 冲突解决
注意点:
- 如果
不是
基于GitHub远程库的最新版本
所做的修改,不能进行push推送
,必须先进行pull操作
拉取下来。 - 拉取下来后如果进入冲突状态,则先
解决冲突
,去掉冲突标记,选用合适的内容,冲突解决后才能push操作
。
3.9 跨团队协作
在他人的远程库地址上点击fork,就可以fork到自己的远程库上
在自己的远程库上,使用git中的
git clone [远程库地址]
操作,克隆到自己的本地库自己在本地进行修改,push推送到远程库中
在远程库的项目中找到 并点击
pull requests
->new pull requests
->create pull request
,然后发送该pull request的信息 ,此时在被fork的原始项目中的pull requests
一栏中就可以看到pull request的信息,并可以进行对话。合并代码,在对话框中就可以点击
merge pull request
进行合并,点击之后填写合并信息被fork的用户就可以将已经更新修改的远程库就可以拉取到本地
3.10 SSH连接方式
ssh-keygen -t rsa -C [将要的登陆用户的邮箱]
执行后会生成SSH目录.ssh/
在
.ssh/
目录下 ,cat id_rsa.pub
获取该id的SSH-RSA的公钥复制到GitHub上的SSH Keys中
在GitHub上添加SSH key
新建使用SSH连接的远程地址别名
git remote add [别名] [ssh方式的连接地址]
使用ssh连接进行push操作
4. Git在eclipse中的应用
4.1 忽略推送配置文件
- 在网址https://github.com/github/gitignore/blob/master/Java.gitignore 找到Java.gitignore文件,此文件为GitHub已经整理好的忽略配置文件。
- 在自己的用户目录,把Java.gitignore文件和.gitconfig文件放在一块。
在Java.gitignore文件中加入以下内容:添加过滤项
1
2
3
4.classpath
.project
.settings
targetJava.gitignore文件内容信息为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
.classpath
.project
.settings
target在.gitconfig配置文件中加入以下内容:
1
2[core]
excludesfile = C:/Users/hxhaaj/Java.gitignore
- 此时注意,该路径内容为
Java.gitignore文件路径
信息,同时,路径分割符必须为正斜线'/',不能为反斜线'\'
。