这篇文章详细介绍了Git的基本概念、工作机制、常用命令以及IDEA集成Git的方法。内容涵盖Git仓库的创建与管理、文件的添加与提交、版本历史查看与切换、分支操作与合并,以及解决合并冲突的方法。同时,文章还指导了如何解决Git使用中常见的问题。此外,还介绍了团队协作中的Git使用流程,包括fork仓库、push修改到原仓库等。
前言
Git工作机制
Git工作仓库
局域网 | 互联网 |
---|---|
GitLab | Github |
Gitee |
Git常用命令
命令 | 说明 |
---|---|
git config --global user.name 用户名 | 设置用户签名(用户名) |
git config --global user.email 邮箱 | 设置用户签名(邮箱) |
git init | 初始化本地库 |
git status | 查看本地库状态 |
git diff | 显示工作目录与暂存区之间的文件变更 |
git add 文件名 | 添加到暂存区(索引区) |
git commit -m "日志信息" 文件名 | 提交到本地库 |
git reflog | 查看提交的历史记录(及版本号) |
git reset --hard 版本号 | 版本切换(可实现撤销commit提交) |
git checkout -- 文件名 | 丢弃工作区的修改 |
git checkout . | 丢弃工作区所有文件的修改 |
git reset HEAD | 把暂存区的修改撤销掉,重新放回工作区 |
工作区(workspace)、暂存区/索引区(index)、本地版本库(repository)、远程仓库(remote)
实例操作
全局范围的签名设置
$ git config --global user.name ooahz
$ git config --global user.email xxxx@ahzoo.cn
查看配置信息
$ cat ~/.gitconfig
**Git 首次安装必须设置一下用户签名,否则无法提交代码。 **
这里设置用户签名和登录 GitHub(或其他代码托管中心)的账号没有任何关系。
签名的作用是区分不同操作者身份。用户的签名信息在每一个版本的提交信息中能够看到,以此确认本次提交是谁进行的
当前仓库范围的签名设置
$ git config user.name ooahz
$ git config user.email xxxx@ahzoo.cn
初始化本地仓库
$ git init
操作完成后,可以在本地看到生成的一个**.git**隐藏文件夹
查看本地库状态
$ git status
On branch master
No commits yet
nothing to commit (create/copy files and use "git add" to track)
新增文件
创建文件
$ vim hello.txt
然后使用vim命令,编写文件,随便写点文字用于测试
$ cat hello.txt
hello world
再次查看状态
$ git status
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
hello.txt
nothing added to commit but untracked files present (use "git add" to track)
添加暂存区
$ git add hello.txt
如果要添加路径下所有文件可以直接使用
git add .
命令
查看状态:
$ git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: hello.txt
提交本地库
$ git commit -m "提交测试" hello.txt
warning: LF will be replaced by CRLF in hello.txt.
The file will have its original line endings in your working directory
[master (root-commit) 9bdf471] 提交测试
1 file changed, 1 insertion(+)
create mode 100644 hello.txt
“日志信息”后面的文件名可省略,省略后表示对此次提交的所有文件添加此日志信息
查看状态:
$ git status
On branch master
nothing to commit, working tree clean
修改文件
vim hello.txt
随便修改几个字符用于测试:
$ cat hello.txt
hello word 001
对比文件
$ git diff
diff --git a/hello.txt b/hello.txt
index 3f5f37d..d0a500f 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1 +1 @@
-hello world
+hello world 001
git diff --cached 或 git diff --staged:显示索引区(暂存区)和最后一次commit(HEAD)之间的文件更改
git diff HEAD:显示工作目录与最后一次commit之间的文件变更
git diff <分支名1> <分支名2> :比较两个分支上最后 commit 的内容的差别
同样提交修改后的文件
$ git add hello.txt
$ git commit -m "修改提交"
[master 67b42c5] 修改提交
1 file changed, 1 insertion(+), 1 deletion(-)
历史版本
$ git reflog
67b42c5 (HEAD -> master) HEAD@{0}: commit: 修改提交
9bdf471 HEAD@{1}: commit (initial): 提交测试
git reflog 查看版本信息
git log 查看版本详细信息
此处的 67b42c5 和 9bdf471 即为版本号
版本切换
将版本切换到初次提交时的版本
$ git reset --hard 9bdf471
HEAD is now at 9bdf471 提交测试
查看文件:
$ cat hello.txt
hello world
Git切换版本,底层其实是移动的HEAD指针
分支操作
在版本控制过程中,同时推进多个任务,为每个任务,我们就可以创建每个任务的单独
分支。使用分支意味着程序员可以把自己的工作从开发主线上分离开来,开发自己分支的时
候,不会影响主线分支的运行。
图解分支的创建与切换:
操作命令
命令 | 说明 |
---|---|
git branch 分支名 | 创建分支 |
git branch -v | 查看分支 |
git checkout 分支名 | 切换分支 |
git merge 分支名 | 把指定的分支合并到当前分支上 |
git branch -D 分支名 | 删除分支 |
实例操作
创建分支
创建名为hot-fix的分支
$ git branch hot-fix
查看分支信息
$ git branch -v
hot-fix 9bdf471 提交测试
* master 9bdf471 提交测试
可以看到创建分支时会将主分支master的内容复制一份
切换分支
切换到hot-fix分支
$ git checkout hot-fix
可以看到右侧的master变成了hot-fix(可见下图)
合并分支
冲突的产生
修改hot-fix分支的文件,与master分支上文件修改的位置保持一致(这样就会产生冲突)
$ vim hello.txt
查看修改
$ cat hello.txt
hello world 002
提交修改
$ git commit -m "分支修改"
[hot-fix acb64ed] 分支修改
1 file changed, 1 insertion(+), 1 deletion(-)
切换回master分支
$ git checkout master
Switched to branch 'master'
M hello.txt
因为之前将master分支的版本切回了未修改时的,所以需要切换回修改后的版本,或者直接重新修改提交亦可;
$ git reset --hard 67b42c5
HEAD is now at 67b42c5 修改提交
查看文件:
$ cat hello.txt
hello world 001
合并分支
由于此时在master,所以需要合并的分支就是hot-fix
git merge hot-fix
冲突报错:
Auto-merging hello.txt
CONFLICT (content): Merge conflict in hello.txt
Automatic merge failed; fix conflicts and then commit the result.
解决冲突
冲突产生的原因:
合并分支时,两个分支在同一个文件的同一个位置有两套完全不同的修改。Git 无法替我们决定使用哪一个。必须人为决定新代码内容。
查看状态:
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: hello.txt
no changes added to commit (use "git add" and/or "git commit -a")
根据返回结果可以看到文件有两个参数,这就造成了冲突
进入文件,手动修改
$ vim hello.txt
<<<<<<< HEAD
hello world 001
=======
hello world 002
>>>>>>> hot-fix
<<<<<<< HEAD 当前分支的代码 ======= 合并过来的代码 >>>>>>> hot-fix
手动修改文件,修改后:
hello world 001
重新提交文件:
$ git add hello.txt
$ git commit -m "修改合并文件"
[master cd73e7f] 修改合并文件
查看文件:
$ cat hello.txt
hello world 002
删除分支
$ git branch -D hot-fix
Deleted branch hot-fix (was acb64ed).
Git 仓库(Git远程仓库操作)
以Github为例(其他仓库也基本大同小异)
创建仓库
点击头像旁边的加号,选择** New repository**;
直接输入仓库名,勾选创建一个初始的readme文件(非必要),然后点击创建即可
j进入仓库后,点击Code即可看到仓库的远程地址
远程仓库操作
命令 | 说明 |
---|---|
git remote -v | 查看当前所有远程地址别名 |
git remote add 别名 远程地址 | 为远程地址添加别名 |
git remote rename 原别名 新别名 | 为远程地址修改别名 |
git remote rm 别名 | 为远程地址删除别名 |
git push 别名 分支 | 推送本地分支上的内容到远程仓库 |
git clone 远程地址 | 将远程仓库的内容克隆到本地 |
git pull 远程库地址别名 远程分支名 | 将远程仓库对于分支最新内容拉下来后与 |
当前本地分支直接合并 |
实例操作
克隆远程仓库
$ git clone https://github.com/ooahz/mytest.git
Cloning into 'mytest'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
克隆指定分支的指定版本
首先克隆指定分支的所有版本(git clone默认克隆所有版本)
$ git clone 仓库地址 -b 分支名称
-b
是--branch
的简写
然后切换版本
$ git reset --hard 版本号
克隆指定分支部分版本
$ git clone --depth=1 仓库地址 --branch 分支名称
--depth=1
表示克隆深度为1,即只克隆最近一次的提交版本;同理--depth=9
表示克隆最近9次的提交版本
如果不想指定分支就直接把--branch 分支名
省略即可
但是,这样克隆会导致无法切换到其他分支,所以需要配合下面命令来切换到其他分支:
添加分支-->获取分支-->切换分支
$ git remote set-branches --add origin 分支名称
$ git fetch origin 分支名称
$ git checkout 分支名称
添加远程仓库
$ git remote add myGitTest https://github.com/ooahz/mytest.git
设置完成后查看别名:
$ git remote -v
myGitTest https://github.com/ooahz/mytest.git (fetch)
myGitTest https://github.com/ooahz/mytest.git (push)
可以看到远程仓库( https://github.com/ooahz/mytest.git)的别名已经被设置成了myGitTest
推送到远程仓库
在本地仓库新建一个文件
添加到本地仓库:
$ git add .
$ git commit -m "测试"
[master 2ac4b5d] 测试
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 "\346\226\260\345\273\272\346\226\207\346\234\254\346\226\207\346\241\243.txt"
将本地仓库分支推送到远程仓库
$ git push myGitTest master
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 286 bytes | 286.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/ooahz/mytest.git
09e2fea..2ac4b5d master -> master
进入github查看:
拉取远程仓库
修改刚刚上传的文件内容(上传时是空文件,上传后添加了一段文字:“ahzoo”
然后新建一个·文件(拉取测试)
开始拉取操作:
$ git pull myGitTest master
remote: Enumerating objects: 8, done.
remote: Counting objects: 100% (8/8), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (6/6), done.
From https://github.com/ooahz/mytest
* branch master -> FETCH_HEAD
2ac4b5d..d0c748e master -> myGitTest/master
Updating 2ac4b5d..d0c748e
Fast-forward
"\346\213\211\345\217\226\346\265\213\350\257\225" | 1 +
...\260\345\273\272\346\226\207\346\234\254\346\226\207\346\241\243.txt" | 1 +
2 files changed, 2 insertions(+)
create mode 100644 "\346\213\211\345\217\226\346\265\213\350\257\225"
git pull 与 git clone 的区别:
git clone是直接将远程仓库克隆到本地,是一个从无到有的过程
git pull 是拉取远程仓库合并到本地,是一个更新过程
总结
还是结合这张图:
工作区(workspace)、暂存区/索引区(index)、本地版本库(repository)、远程仓库(remote)
- 前提
可以看到进行git操作之前,必须要先创建工作区。即进行git操作时要先拥有一个git仓库,如果没有则需要使用git init命令初始化git仓库
而进行远程仓库操作时,都是需要远程仓库支持。即进行远程仓库操作时需要关联远程仓库,如果没有则需要使用git remote命令关联远程仓库
示例:
$ git init
$ git remote add origin https://github.com/ooahz/mytest.git
- 拉取操作
在完成上面两个前提操作后,我们就可以进行拉取操作。结合上面那张图,可以看到拉取操作只需要从远程仓库拉取(pull)即可。
示例:
$ git pull origin master
- 推送操作
在完成上面两个前提操作后,我们就可以进行推送操作。结合上面那张图,可以看到推送操作需要先将本地仓库添加到索引区,然后再提交到本地库,最后才能进行推送操作。
示例:
$ git add .
$ git commit -m "版本推送说明"
$ git push origin master
团队协作
团队内协作
跨团队协作
fork别的仓库到自己仓库(dev分支)-->在自己仓库修改-->pull推送给原作者(master分支)
IDEA整合Git
配置Git 忽略文件
忽略原则:
- 忽略操作系统自动生成的文件,比如缩略图等;
- 忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;
- 忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。
举个例子:
方法一
创建忽略文件git.ignore(可以自定义文件名)
参考模板:
# 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
.idea
*.iml
然后添加忽略文件:
在C盘的用户路径下,找到名为.gitconfig的文件;
打开后可以看到之前配置的全局范围签名信息,在后面添加忽略文件路径即可
[user]
name = ooahz
email = xxx@ahzoo.cn
[core]
excludesfile = C:/Users/ahzoo/git.ignore
方法二
打开IDEA:File | Settings | Editor | File Types;
在Ignore files and folders中添加需要忽略的文件或者文件夹
配置Git路径
初始化Git仓库
VCS-->import into Version Control-->Creat Git Repository;
然后选择要创建本地仓库的项目
添加到暂存区
右键项目,Gitt-->Add
提交到本地库
右键项目,Gitt-->Commit Directory
选择要提交的文件,输入提交信息,然后点击commit提交;
切换版本
右下角点击Git,选择Log,右键要切换的版本,选择Checkout Revision
分支操作
项目右键选择Git-->Repository -->Branches (或者直接点击右下角的分支名)
创建分支
在弹出的分支弹窗中,点击new Branch;
输入分支名,创建即可
切换分支
直接在弹出的分支弹窗中选择要切换的分支,然后点击Checkout即可;
切换完成后,在IDEA右下角可以看到当前分支
合并分支
直接在弹出的分支弹窗中选择要切换的分支,然后点击Merge into Current即可;
冲突解决
可参照前面Git中的解决方法
Bug分支
适用场景:线上需要紧急修复bug,而当前dev分支中又有开发到一半的需求,因此此时不能在dev分支上进行修复,就需要创建一个Bug分支,对当前Bug进行修复。
因为要对master分支的bug进行修复,所以,在Idea中打开分支;
在master分支中选择New Branch from Selected
输入分支名
在bug分支修复完bug后,切回master分支
然后选择刚才修复bug的分支,选择Marge into Curent合并到master分支即可
修复完master上的分支后再切回dev分支,将修复bug的分支合并到dev分支
合并完后删除bug分支
IDEA整合GitHub
Gitee同理,只需要在IDEA安装Gitee插件即可;
配置SSH
配置SSH密钥,实现免密登录(首次提交时仍需要验证密码)
$ ssh-keygen -t rsa -C "github绑定的邮箱"
连续敲回车确定,然后看到提示秘钥以保存在xxx路径下(如果没有出现提示就多敲几次回车)。
在提示的路径下找到id_rsa文件,复制文件内容。
登陆你的Github帐号,点击头像进入settings,点击SSH and GPG keys-->New SSH key,输入刚才复制的密钥命名保存,完成(提交仓库的链接记得选SSH而不是HTTPS)
创建个人访问令牌(Personal Access Tokens)
点击右侧头像,依次选择Settings→Developer settings→Personal access tokens→Generate new token;
输入note名,勾选需要的功能(不知道就全√),然后选择底部的生成令牌按钮;
复制生成的Token,需要注意的是,此Token只会显示一次,所以需要妥善保管(丢了就按照步骤重新创建一次)
添加账户
依次打开:File | Settings | Version Control | GitHub
输入账号密码,或者左上角选择Use Token(使用个人访问令牌登录)
分享项目到远程仓库
VCS-->Import into Version Control-->Share Project on Github
设置仓库名(Repository name),远程版本库名(Remote),简介(Description),点击Share分享
克隆远程仓库到本地
进入IDEA首页,选择Get from Version Control
输入远程仓库地址:
点击CLONE等待克隆完成
设置本地库
点击顶部菜单栏的VCS-->Create Git Repository,设置Git仓库
设置完Git仓库后,顶部菜单的VCS会变成Git
修改本地库
如果本地库设置错了,可在设置中进行修改:
点击:File | Settings | Version Control | Directory Mappings
可以在这里对本地库进行相应的操作
添加远程仓库
点击顶部菜单栏的Git-->Manage Remotes
点击+号,设置远程仓库地址,并自定义别名
拉取远程项目到本地
修改本地项目:
拉取远程仓库:
选择项目右键,Git-->Repository-->Pull
如之前未设置Git仓库及关联远程仓库,会出现下面的弹窗提示进行相关操作:
设置当前项目路径,远程仓库地址(一般都是默认即可),然后点击Pull,开始拉取远程仓库
推送项目到远程仓库
首先将项目【提交到本地库】(参照上文的IDEA整合Git部分);
然后将本地库上传到远程库;
选择项目右键,Git-->Repository-->Push
后记
报错一:
fatal: unable to access 'https://github.com/ooahz/mytest.git/': OpenSSL SSL_read: Connection was reset, errno 10054
解决方法,使用SSH代替HTTPS(必须要先配置SSH才行)
报错二:
账户密码输入正常,却无法登录
Logon failed, use ctrl+c to cancel basic credential prompt.
解决方法:
使用个人令牌登录;
在密码栏输入个人令牌即可
问题三:
git push时提示:
Everything up-to-date
原因:修改本地仓库时未进行提交
解决方法:添加本地仓库并提交:
$ git add .
$ git commit -m "推送测试"
问题四:
使用git add
命令时提示:
The following paths are ignored by one of your .gitignore files:
App.class
Use -f if you really want to add them.
解决方法一:
使用-f
强制添加
$ git add -f App.class
解决方法二:
检查是否为.gitignore配置的问题:
使用命令git check-ignore -v 文件名
$ git check-ignore -v App.class
.gitignore:7:*.class App.class
可以看到是.gitignore配置文件的第7行忽略
.class
文件
问题五:
配置SSH时出现提示:
unknow key type ras
解决方法:
使用以下命令替换
ssh-keygen -C"邮箱地址"
问题六:
使用IDEA推送(pull)项目时失败,报错:
unable to access 'https://github.com/ooahz/methodTest.git/': OpenSSL SSL_read: Connection was reset, errno 10054
解决方法:
修改远程仓库地址(remote)
选择项目右键,Git-->Repository-->Remotes
新建一个,如果远程版本库名就直接编辑已有的远程仓库地址;
因为使用HTTPS报错了,所以需要使用SSH连接;
填入远程版本库名(默认为origin)和远程仓库的SSH地址,点击OK保存
问题七:
修改/创建remote时报错:
The authenticity of host 'github.com (20.205.243.166)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])?
原因:本地SSH与远程仓库不一致;
解决方法:参照【配置SSH】将SSH设为一致即可
这里还没有评论哦
快来发一条评论抢占前排吧