最近重新梳理了这些年使用git
的一些用法和问题,方便自己记忆查找。
Git 简介
定义
Git
是一个开源的分布式版本控制系统,是 Linus Torvalds
为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件,可以有效、高速地处理从很小到非常大的项目版本管理。
官网
https://git-scm.com/
下载安装
很简单,不是本文重点。
配置
初次使用,需要配置邮箱和用户名字
git config --global user.email "2312@l16.com"
git config --global user.name "xiaoyu"
Git 初体验
基本思想
基本命令
-
初始化
# cd /test git init
-
添加一个文件
vi test.txt
添加内容,保存
-
添加到本地暂存区
git add test.txt
-
提交文件到本地仓库
$ git commit -m "first commit" [master (root-commit) 11fd92e] first commit 1 file changed, 1 insertion(+) create mode 100644 test.txt
-
查看工作区、暂存区的状态
$ git status On branch master nothing to commit, working tree clean
-
查看历史提交
$ git log commit 11fd92e23dc8e436251d30bf8cfb0273b0668fd1 (HEAD -> master) Author: **** <z***4@163.com> Date: Wed Nov 25 11:49:32 2020 +0800 first commit
再次修改test.txt
-
查看状态
$ git status On branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: test.txt no changes added to commit (use "git add" and/or "git commit -a")
红色粗体提示,
test.txt
文件有修改,但是没有提交的暂存区或者版本库,提示可用什么命令去操作 -
再次添加到暂存区和本地仓库
git add test.txt git commit -m "second commit"
-
再次查看日志
$ git log commit 58213db8d59163d8d0a380cce7d6da2e3ed03b51 (HEAD -> master) Author: **** <z***4@163.com> Date: Wed Nov 25 13:12:19 2020 +0800 second commit commit 11fd92e23dc8e436251d30bf8cfb0273b0668fd1 Author: **** <z***4@163.com> Date: Wed Nov 25 11:49:32 2020 +0800 first commit
-
怎么回退到第一次提交的内容呢,再次查看log
$ git log commit 11fd92e23dc8e436251d30bf8cfb0273b0668fd1 (HEAD -> master) Author: **** <z***4@163.com> Date: Wed Nov 25 11:49:32 2020 +0800 first commit
现在只有回退的那个版本的信息,之前的最新版本不见了,怎么回退到最新版本呢?
-
使用
reflog
git reflog
可以查看所有分支的所有操作记录(包括已经被删除的commit
记录和reset
的操作)$ git reflog 11fd92e (HEAD -> master) HEAD@{0}: reset: moving to 11fd92e23dc8e436251d30bf8cfb0273b0668fd1 58213db HEAD@{1}: commit: second commit 11fd92e (HEAD -> master) HEAD@{2}: commit (initial): first commit
-
再回退到最新版本
$ git reset --hard 58213db HEAD is now at 58213db second commit
-
再次查看全部记录
$ git reflog 58213db (HEAD -> master) HEAD@{0}: reset: moving to 58213db 11fd92e HEAD@{1}: reset: moving to 11fd92e23dc8e436251d30bf8cfb0273b0668fd1 58213db (HEAD -> master) HEAD@{2}: commit: second commit 11fd92e HEAD@{3}: commit (initial): first commit
HEAD当前版本
其实每次提交,串联起来,就是一个链表,HEAD
就好比指向当前节点的指针,切换版本,也就是移动HEAD
指针的感觉。
这有助于理解后续的的git reset
git 命令详解
git clone
克隆远程仓库代码到本地
git clone https://gitee.com/xiaoxiaoyunlu/mano-mall.git
功能:
- 完整的克隆远程库为本地库
- 为本地库新建origin别名
- 初始化本地库
git status
初始
$ git status
On branch master
No commits yet
nothing to commit (create/copy files and use "git add" to track)
有文件未被跟踪
新建一个文件
$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
test2.txt
nothing added to commit but untracked files present (use "git add" to track)
有文件需要被提交
$ git add test2.txt
warning: LF will be replaced by CRLF in test2.txt.
The file will have its original line endings in your working directory
dell@DESKTOP-IB48TPN MINGW64 /c/Mano/mano/study/test_git (master)
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: test2.txt
没有需要提交的
$ git commit -m "new file"
[master 94bc643] new file
1 file changed, 1 insertion(+)
create mode 100644 test2.txt
dell@DESKTOP-IB48TPN MINGW64 /c/Mano/mano/study/test_git (master)
$ git status
On branch master
nothing to commit, working tree clean
有文件被修改
修改test2.txt 文件后,查看状态
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: test2.txt
有文件被删除
删除已经提交的文件,查看状态
$ rm -rf test2.txt
dell@DESKTOP-IB48TPN MINGW64 /c/Mano/mano/study/test_git (master)
$ git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
deleted: test2.txt
no changes added to commit (use "git add" and/or "git commit -a")
有文件需要被删除
如果的确需要删除,提交呢
$ git add test2.txt
dell@DESKTOP-IB48TPN MINGW64 /c/Mano/mano/study/test_git (master)
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: test2.txt
git diff
比较工作区和暂存区的所有文件差异
git diff HEAD|HEAD^|HEAD~|哈希索引值 <file name> #比较工作区跟本地库的某个版本的**指定文件**的差异
比较工作区和暂存区的指定文件差异
git diff <file name>
比较工作区和本地库的某个版本的指定文件的差异
git diff HEAD test.txt # 当前版本
git diff HEAD^ test.txt # 前一个版本
git diff HEAD~ test.txt # 前一个版本
git diff 66a3fc5 test.txt # 制定哈希值 版本
git add
添加文件到暂存区
添加单个文件
git add test2.txt
添加目录
git add test2
添加当前所有文件夹
git add .
git checkout
前提是,这个文件,已经被git管理了。
丢弃修改
未提交到暂存区
比如,本地修改了文件,则查看状态
$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
test4.txt
nothing added to commit but untracked files present (use "git add" to track)
这时候,应该要提交到暂存区的,但是不想修改了,就是当前修改的内容丢弃掉,也不用提交到暂存区了,怎么办呢?
$ git checkout -- test4.txt # 注意,必须加 -- 不然就变成了切换分支了
等价于
git restore test4.txt # 修改当前修改,其实就是恢复到未修改前的状态
提交到暂存区
如果已经提交到暂存区,则要使用如下命令:
# 默认是--mixed 模式,保留工作区,清空暂存区
$ git reset HEAD test4.txt
Unstaged changes after reset:
M test4.txt
# 因为我们要丢弃修改,所以工作区的也要清空,继续使用这种命令
$ git checkout -- test4.txt
切换分支
详情看下面的分支管理部分
git rm
从暂存区删除
git rm --cached test.txt
git restore
从暂存区回复
如果提交到暂存区(git add
),但是发现问题,需要回退怎么办呢
git restore --staged test.txt #表示从暂存区将文件的状态修改成 unstage 状态
git restore --staged *.txt #表示将所有暂存区的txt文件恢复状态
git restore --staged . #表示将当前目录所有暂存区文件恢复状态
--staged
参数就是表示仅仅恢复暂存区的 ,也就是工作区的修改还在哦,修改并没有被丢弃
从版本库回复
更严重点,比如已经提交到版本(git commit
),但是发现问题,需要回退怎么办呢
$ git restore -s HEAD~1 test.txt # 该命名表示将版本回退到当前快照的前一个版本
# 或者直接根据哈希索引恢复
$ git restore -s 91410eb9 test.txt # 改命令指定明确的 commit id ,回退到指定的快照中
也可以直接回退
$ git reset --soft HEAD^ # 该命令表示撤销 commit 至上一次 commit 的版本
直接回复删除的文件
git restore
命令,默认是带着 --worktree
参数的,意思是撤销工作区的修改
rm -rf test.txt
$ git restore test3.txt
error: pathspec 'test3.txt' did not match any file(s) known to git
这是因为,还没有提交给git, 所以你本地删除了,就不能指望通过git restore
回复文件了, 这就是真的删除,只能从物理层面恢复
所以,起码要提交到暂存区,归git管理了才可以恢复
git add test.txt
rm -rf test.txt
git restore test.txt
git log
查看git的日志信息
查看log
$ git log
commit 11fd92e23dc8e436251d30bf8cfb0273b0668fd1 (HEAD -> master)
Author: **** <z***4@163.com>
Date: Wed Nov 25 11:49:32 2020 +0800
first commit
查看简介信息
日志消息太多了,只以简洁的一行显示,包含简洁哈希索引值
# 以漂亮的一行显示,包含全部哈希索引值
$ git log --pretty=oneline
11fd92e23dc8e436251d30bf8cfb0273b0668fd1 (HEAD -> master) first commit
查看简要hash信息
哈希索引值太长了,能否看到所写的哈希索引值呢
$ git log --oneline
11fd92e (HEAD -> master) first commit
git reflog
git reflog
可以查看所有分支的所有操作记录(包括已经被删除的commit
记录和 reset
的操作)
$ git reflog
11fd92e (HEAD -> master) HEAD@{0}: reset: moving to 11fd92e23dc8e436251d30bf8cfb0273b0668fd1
58213db HEAD@{1}: commit: second commit
11fd92e (HEAD -> master) HEAD@{2}: commit (initial): first commit
git reset
撤销操作,当前版本是 HEAD
reset模式
-
–hard
reset --hard 会在重置 HEAD 和branch的同时,重置stage区和工作目录里的内容。当你在 reset 后面加了 –hard 参数时,你的stage区和工作目录里的内容会被完全重置为和HEAD的新位置相同的内容。换句话说,就是你的没有commit的修改会被全部擦掉
-
–soft
reset --soft 会在重置 HEAD 和 branch 时,保留工作目录和暂存区中的内容,并把重置 HEAD 所带来的新的差异放进暂存区。
-
–mixed
reset 如果不加参数,那么默认使用 –mixed 参数。它的行为是:保留工作目录,并且清空暂存区。也就是说,工作目录的修改、暂存区的内容以及由 reset 所导致的新的文件差异,都会被放进工作目录。简而言之,就是「把所有差异都混合(
mixed
)放在工作目录中」
直接回到指定哈希值所对应的版本
# 11fd92e23dc8e436251d30bf8cfb0273b0668fd1 是第一次提交的commit hashcode
$ git reset --hard 11fd92e23dc8e436251d30bf8cfb0273b0668fd1
HEAD is now at 11fd92e first commit
后退版本
#一个^表示回退一个版本
git reset --hard HEAD^ # 回退一个版本
git reset --hard HEAD^^ # 回退两个版本
等价于:
# 波浪线~后面的数字表示后退几个版本
git reset --hard HEAD~1 # 后退一个版本
git reset --hard HEAD~2 # 后退两个个版本
已经push到远程
# log 查看版本 得到你需要回退一次提交的commit id
git log -v
# 回退到之前的版本
git reset --hard <commit_id>
直接提交会报错如下:
$ git push -u origin master
To https://gitee.com/xiaoxiaoyunlu/mano-mall.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'https://gitee.com/xiaoxiaoyunlu/mano-mall.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
因为远程和本地不一样,提示错误,所以要强制回退
# 强制提交一次,之前错误的提交就从远程仓库删除
git push origin HEAD --force
或者:
git push -f origin master
git branch
$ git log
commit 95015cb98d738072c8bec15f7656f8a0371c8ef9 (HEAD -> master)
Master 分支
默认是Master
分支,其实所谓的HEAD
指针,指向的是当前Master
分支的版本。
正常情况下,Master
一般用于最稳定版本代码的维护,用于新版本发布。
为什么需要创建不同的分支
主线Master
分支,是最重要的,但是一个项目里面,很多人来开发,那么谁都可以来再Master
分支里面直接修改吗,很危险的啊老铁。
正常的做法就是,每个人在Master
分支上拉出一个个人的开发分支branch
,等各自修改后以后,再合并分支,回归代码到主线Master
分支。
创建分支
# 创建分支
git branch test_dev
创建分支,要切换到分支下开发,所以可以有更快捷的命令,创建分支以后直接切换到分支
$ git checkout -b test_prod
Switched to a new branch 'test_prod'
查看分支
$ git branch -v
* master 95015cb test4
test_dev 95015cb test4
修改分支名称
一旦创建不合适了,可以修改,具体如下:
# 修改本地分支名称
git branch -m old_branch new_branch
# 删除远程的old 分支
git push origin :old_branch
# 推送新分支 到 远程仓库
git push --set-upstream origin new_branch
切换分支
# 切换到分支
$ git checkout test_dev
Switched to branch 'test_dev'
删除分支
当前所处分支不能直接删除
$ git branch -d test_prod
error: Cannot delete branch 'test_prod' checked out at 'C:/Mano/mano/study/test_git'
因为当前在test_prod
,所以是不能直接删除分支的,要先切换到其他分支,再删除,就好比当前分支使用中,不能删除。
$ git checkout master
$ git branch -v
* master 95015cb test4
test_dev 95015cb test4
test_prod 95015cb test4
dell@DESKTOP-IB48TPN MINGW64 /c/Mano/mano/study/test_git (master)
$ git branch -d test_prod
Deleted branch test_prod (was 95015cb).
注意,可能会删除失败,如果分值代码不一致的情况。
当前分支有代码没有提交到版本库
$ git checkout -b test_12
Switched to a new branch 'test_12'
vi test11.txt
这个时候切换分支,可以删除,但是,test11.txt
还是没有被git
管理
# 新建分支测试
$ git checkout -b test_13
Switched to a new branch 'test_13'
# 当前分支下,add
git add test11.txt
注意,这时候是在分支test_13
下,被提交到暂存区,还没有提交到版本库,还是可以直接删除的
猜测:所有分支是共享工作区和暂存区的,待验证。
当前分支有代码已经提交到版本库
# 提交到代码库
$ git commit -m "test5"
[test_13 d558e91] test5
1 file changed, 1 insertion(+)
create mode 100644 test5.txt
# 切换到master分支 , 删除 分支 test_13
$ git branch -d test_13
error: The branch 'test_13' is not fully merged.
If you are sure you want to delete it, run 'git branch -D test_13'.
提示,当前分支存在没有合并(git merge
)的代码,也就是出现代码不一致,是否强制删除?
# 使用 -D 强制删除
git branch -D test_13
删除远程分支
注意,这个必须谨慎操作
git push origin --delete test_14 # 删除远程分支
分支合并
分支开发merge到master
比如,项目组新来了个同事,开发步骤如下:
-
先给新同事开发项目开发分支
git checkout -b test_14
-
分支下开发新功能
# 创建了文件`test14.txt` vi test14.txt
-
功能测试没问题,要发版本了
要发布,首先,就得把代码从分支
test_14
,合并到master
分支,确认没有问题,才可以审核发布。# git merger [被合并分支] [要合并的分支] $ git merge test_14 master Updating 95015cb..d04ca5c Fast-forward test14.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 test14.txt
多人分支merge
一个项目组,大系统,很多个同事一起开发,怎么办呢
-
主分支
# 比如有公用模块 test.txt vi test.txt init
-
同事小张负责模块1
git checkkout -b dev_zhang
vi test.txt
# 修改代码
init
model 1
git add test.txt
git commit -m "dev_zhang commit model 1"
修改代码只在dev_zhang
下面
-
同事小李负责模块2
git checkout -b dev_li vi test.txt # 修改代码 init model 2 git add test.txt git commit -m "dev_li commit model 2"
修改代码只在
dev_li
下面 -
切换到主分支
master
git checkout master
此时,主分支
master
并没有同事张和同事小李的代码,所以,需要合并分支到到主分支master
-
合并小张代码到主分支
$ git merge dev_zhang Updating d04ca5c..4749995 Fast-forward test.txt | 1 + 1 file changed, 1 insertion(+)
没有问题,因为没有冲突代码,查看日志如下:
$ git log --pretty=oneline 4749995910cfcc12fe2619489cc0fb3af60b316f (HEAD -> master, dev_zhang) zhang modify test
可以看到,此时
master
和分支dev_zhang
的代码保持一致了。 -
合并小李代码到主分支
$ git merge dev_li Auto-merging test.txt CONFLICT (content): Merge conflict in test.txt Automatic merge failed; fix conflicts and then commit the result.
有冲突代码,为什么呢,因为现在小张的代码已经合并到主分支了,现在小李要合并到主分支,代码内容有冲突了,需要先处理代码冲突问题,才能顺利合并哦
-
查看有冲突的文件
# 注意,当前还在master 主分支 dell@DESKTOP-IB48TPN MINGW64 /c/Mano/mano/study/test_git (master|MERGING) $ vi test.txt init <<<<<<< HEAD model 1 ======= model 2 >>>>>>> dev_li
======
是分界线<<<<<<
是已经存在的版本的分界线>>>>>>
是当前分支里面的分界线
既然找到了冲突代码,就得解决,是保存都要呢,还是只要自己的,确定好
-
修改后提交
# 比如修改如下: init model 1 model 2 git add test.txt git commit -m "li handle confit to commit"
-
查看日志
dell@DESKTOP-IB48TPN MINGW64 /c/Mano/mano/study/test_git (master) $ git log --pretty=oneline 652c5bbe54a894bce34da322e193e2d748a32318 (HEAD -> master) li handle confit to commit 66a3fc5f80cb8e461c51f1d2607ba26f0d12f18e (dev_li) dev_li commit model 2 4749995910cfcc12fe2619489cc0fb3af60b316f (dev_zhang) dev_zhang commit model 1 d04ca5cbbab73950eeb75a7fe7e1fd6f357ec8b8 (test_14) test14 95015cb98d738072c8bec15f7656f8a0371c8ef9 test4
git config
主要是配置一下git需要的环境变量字段什么的。
分类和优先级
注意,优先级从上到下,一次递减,存在同名的配置,优先级高的会覆盖优先级低的。
-
仓库级别
git config --local
仓库配置,一般在当前工作区的
.git
目录的config
文件里面[core] repositoryformatversion = 0 filemode = false bare = false logallrefupdates = true symlinks = false ignorecase = true
-
全局级别
git config --global
-
系统级别
git config --system
系统级别,比如当前
window
系统git
的安装目录下的etc\gitconfig
查看配置 -l
全部配置
$ git config -l
注意,这份列表,是融合了三个级别的配置哦
仓库级别
$ git config --local -l
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.symlinks=false
core.ignorecase=true
全局级别
$ git config --global -l
user.name=x*******u
user.email=z****4@163.com
系统级别
$ git config --system -l
diff.astextplain.textconv=astextplain
filter.lfs.clean=git-lfs clean -- %f
filter.lfs.smudge=git-lfs smudge -- %f
filter.lfs.process=git-lfs filter-process
filter.lfs.required=true
http.sslbackend=openssl
http.sslcainfo=C:/Program Files/Git/mingw64/ssl/certs/ca-bundle.crt
core.autocrlf=true
core.fscache=true
core.symlinks=false
pull.rebase=false
credential.helper=manager
修改配置 -e
git config --local -e #编辑仓库配置
git config --global -e #编辑全局配置
git config --system -e #编辑系统配置
当然,修改单条配置的话, 直接修改
git config --global user.name "xiaoyu"
添加字段
git config --global add user.name "1231231"
删除字段
git config --global unset user.name
设置别名
之前的很多命令,是不是感觉有些长啊,不是很方便
git log --pretty=oneline
git commit -m "2"
能不能简化一下呢,比如:
git log one # 就标识 git log --pretty=oneline
git cm -m "2" # 标识 git commit -m "2"
完全可以,git
支持别名配置哦
git config --global alias.bv branch -v
git config --global alias.logone log --pretty=oneline
查看全局配置
$ git config --global -l
user.name=x*****u
user.email=z****@163.com
alias.logone=log
alias.bv=branch
貌似,和我们修改的不一样啊,那就直接编辑文件修改吧
# 编辑全局配置 修改
git config --global -e
# 查看
$ git config --global -l
user.name=xiaoxiaoyunlu
user.email=zjxzz0714@163.com
alias.logone=log --pretty=oneline
alias.bv=branch -v
测试:
$ git bv
dev_li 66a3fc5 li modify test
dev_zhang 4749995 zhang modify test
* master 652c5bb li modify new
test_14 d04ca5c test14
git tag
为什么需要打标签
$ git logone
652c5bbe54a894bce34da322e193e2d748a32318 (HEAD -> master) li modify new
66a3fc5f80cb8e461c51f1d2607ba26f0d12f18e (dev_li) li modify test
4749995910cfcc12fe2619489cc0fb3af60b316f (dev_zhang) zhang modify test
这么长的commit id
和 备注,毕竟不容易记住啊,也很难记住哪个版本修改了什么内容,怎么呢?
就好比,ip地址123.67.342.90
,很很难记住,我们就用域名www.baidu.com
去映射对应,很方便,我们也可以试着给每个稳定的提交版本设置一个容易记住的标签。
给commitid打标签
# 给某个commitid 打版本标签
$ git tag v0.0.1 11fd92e -m "zhang model 2 done"
# 默认不写commitid 就是给当前最新版本打标签
$ git tag v1.0.0
删除标签
git tag -d v0.0.1
查看tag 列表
$ git tag
v0.0.9
v1.0.0
查看日志
$ git logone
652c5bbe54a894bce34da322e193e2d748a32318 (HEAD -> master, tag: v1.0.0) li modify new
66a3fc5f80cb8e461c51f1d2607ba26f0d12f18e (dev_li) li modify test
4749995910cfcc12fe2619489cc0fb3af60b316f (tag: v0.0.9, dev_zhang) zhang modify test
忽略文件
有些文件,其实没有必要提交到git,比如,.class
或者.jar
等,怎么告诉git
一下,提交的时候忽略,不去提交呢,可以建立一个.gitignore
文件
vi .gitignore
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
当然,这个文件要提交到git
去知道
git add .gitignore
git commit -m "ignore file format"
测试,
# 新建一个jar
vi m1.jar
$ git status
On branch master
nothing to commit, working tree clean
被忽略了,都不会去跟踪了。
远程仓库
理解远程仓库
简单来说,远程仓库实际上就是保持在服务器上的Git仓库,用来备份Git文件以及实现代码共享。
因为开发的代码,不可能一直保留在个人开发环境里面的本地仓库,都需要有一个部署在远程服务器的远程仓库,可以是github
,也可以是gitee
,或者还可以在自己的阿里云服务器上搭建gitlab
。
git remote
主要是用来关联和推送下载远程仓库
-
查看远程仓库
$ git remote
-
没有,那就添加一个
origin
是起源,源头的意思,可以看做是远程仓库的别名https://gitee.com/xiaoxiaoyunlu/mano-mall.git
,这是个人基于微服务开发的微型电商项目的远程码云地址。
git remote add origin https://gitee.com/xiaoxiaoyunlu/mano-mall.git
-
再次查看
$ git remote origin # -v 详细信息 $ git remote -v origin https://gitee.com/xiaoxiaoyunlu/mano-mall.git (fetch) origin https://gitee.com/xiaoxiaoyunlu/mano-mall.git (push)
只有把本地仓库和远程仓库关联起来,才可以把代码推送到远程仓库。
-
删除远程仓库别名
git remote rm <别名>
git push
推送到master分支
# 推送本地代码到远程仓库master分支
git push -u origin master
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
正常情况下,第一次push
都会提示权限的问题Permission denied (publickey)
,这是因为,本地仓库和远程仓库交互,需要有一个访问权限publickey
,不然怎么保证安全性呢?
配置 ssh_key
生成ssh_key
注意,这里配置的是码云gitee
$ ssh-keygen -t rsa -C *******@126.com
Generating public/private rsa key pair.
# 注意,这里是保存秘钥文件的路径
Enter file in which to save the key (~/.ssh/id_rsa): id_rsa_gitee
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in id_rsa_gitee.
Your public key has been saved in id_rsa_gitee.pub.
The key fingerprint is:
...
The key's randomart image is:
...
基本上一路按照提示操作即可,
cd ~/.ssh
该目录下生成文件如下: id_rsa_gitee
和 id_rsa_gitee.pub
。
其中id_rsa_gitee.pub
存放的是公钥publickey
配置到gitee
-
登录码云,进入到设置界面,点击
SSH公钥
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A3efZ7qA-1606464685466)(Git实战.assets/1606454275889.png)]
-
标题随便写,可以写
rsa_gitee
,复制id_rsa_gitee.pub
里面的内容到公钥里面,保存 -
测试
$ ssh -T git@gitee.com The authenticity of host 'gitee.com (212.64.62.183)' can't be established. ECDSA key fingerprint is SHA256:FQGC9Kn/eye1W8icdBgrQp+KkGYoFgbVr17bmjey0Wc. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added 'gitee.com,212.64.62.183' (ECDSA) to the list of known hosts. Hi xiaoxiaoyunlu! You've successfully authenticated, but GITEE.COM does not provide shell access.
出现这个,就是配置成功了
-
重新
push
$ git push -u origin master Enumerating objects: 5, done. Counting objects: 100% (5/5), done. Delta compression using up to 4 threads Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 323 bytes | 161.00 KiB/s, done. Total 3 (delta 2), reused 0 (delta 0), pack-reused 0 remote: Powered by GITEE.COM [GNK-5.0] To https://gitee.com/xiaoxiaoyunlu/mano-mall.git 5417c4a..8ebfb0b master -> master Branch 'master' set up to track remote branch 'master' from 'origin'.
推送到其他分支
是不是只能推送到远程仓库的master
分支呢,当时不是了,制定推送的分支名称就可以了,具体如下:
# 推送本地代码到远程仓库的dev_mall分支
git push -u origin dev_mall
git pull
每次提价代码到远程仓库之前,记得使用git pull
拉取一下远程的最新代码,防止团队里面的其他成员已经提交了新代码,这样方便提前发现冲突,解决后提交
$ git pull
remote: Enumerating objects: 16, done.
remote: Counting objects: 100% (16/16), done.
remote: Compressing objects: 100% (15/15), done.
remote: Total 15 (delta 8), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (15/15), 7.41 KiB | 32.00 KiB/s, done.
From https://gitee.com/xiaoxiaoyunlu/mano-mall
e184eb4..432a799 master -> origin/master
CONFLICT (add/add): Merge conflict in README.md
Auto-merging README.md
warning: LF will be replaced by CRLF in README.md.
The file will have its original line endings in your working directory
Automatic merge failed; fix conflicts and then commit the result.
如果直接git pull
失败的话,试试如下命令:
git pull --rebase origin master
git fetch
-
参考文章:
- https://blog.csdn.net/a19881029/article/details/42245955
- https://blog.csdn.net/weixin_41975655/article/details/82887273
-
git pull
很粗暴的 会将本地库更新至远程库的最新状态- 本地代码是
merge
后的状态,共存差异,本地修改后,解决冲突后,统一提交
init <<<<<<< HEAD model 1 ======= model 2 >>>>>>> dev_li
- 注意,
git pull
简单粗暴,直接尝试merge
,隐藏了过程的细节问题,看似危险,但是新版本还是需要我们自己手动去解决冲突的,所以,不用担心,放心使用。
- 本地代码是
-
git fetch
只会将本地库所关联的远程库的commit id
更新至最新-
比如本地
commitid
是1
,如果远程origin
没有更新的话,应该也是1
,实际情况是,远程最新commtid
是3
,使用git fetch
以后,本地保存的origin
的commitid
也会变成最新的3
-
但是本地库代码没有变化,也没有出现共存差异的情况
-
这时候,再去
merge
的话,如果本地和远程的相同代码不一样,才会提示冲突,需要我们手动解决冲突后提交,生成最新版本commit
是4
-
-
总结起来
git pull
=git fetch
+git merge
- 只是表象,实际肯定有出入,待查证
git fork
一般是在github
或者码云
界面操作的,点击右边的fork
按钮,把别人远程仓库的代码,复制到自己的远程仓库里面,但是你还需自己git clone
到本地来查看和开发修改。
协同开发流程总结
初始提交
## cd 到工作目录
git init
touch README.md
git add README.md
git commit -m "first commit"
git remote add origin https://gitee.com/xiaoxiaoyunlu/mano-mall.git
git push -u origin master
提交分支到远程master
# 切换到 分支
git checkout dev_14
# 保险起见,还是先pull 防止已经更新
git pull --rebase origin master
# 切换回 master
git checkout master
# 合并分支
git merge dev_14
# 提交
git push -u origin master
注意,可能git pull
失败,记得试试:
git pull --rebase origin master
提交到远程开发分支
# 如果master已经有更新了
#切换到master分支
git checkout master
# 拉去最新代码
git pull
# 切换到 待合并分支
git checkout dev
# 合并到 开发分支
git merge master
# 提交到开发分支
git push -u origin dev
window上多个git共存配置
需求
比如,有些项目提交到github
,其他项目管理在gitee
,甚至gitlab
都有,这需求要在window
配置多个git
支持了,否则无法正常工作
前提是,每个git
端,都注册有账号,记住,邮箱最好使用不同的。
清除已有的配置
比如,可能已经设置了邮箱和用户名
$ git config --global user.name "你的名字"
$ git config --global user.email "你的邮箱"
清除掉已有配置:
$ git config --global --unset user.name "你的名字"
$ git config --global --unset user.email "你的邮箱"
配置git多版本
生成ssh-key
ssh-keygen -t rsa -f ~/.ssh/id_rsa.gitee -C "your email@example.com"
也可以进入该目录,不用指定路径
cd ~/.ssh
$ ssh-keygen -t rsa -C "your email@example.com"
有几个git
客户端,就操作几遍,记得修改容易记住的标题,比如,当前目录已生成文件列表如下:
id_rsa_gitee
id_rsa_gitee.pub
id_rsa_github
id_rsa_github.pub
分别配置到git界面
配置git config
# 记住,必须是这个目录
cd ~/.ssh/
# 新建配置文件
vi config
内容如下:
#default github
Host github.com
HostName github.com
IdentityFile ~/.ssh/id_rsa_github
Host gitee.com
HostName gitee.com
IdentityFile ~/.ssh/id_rsa_gitee
注意保存。
添加秘钥到ssh的agent中
-
最好先删除已有的配置
ssh-add -D
若执行
ssh-add -D
是出现这个错误:Could not open a connection to your authentication agent
,则先执行如下命令:ssh-agent bash
-
挨个添加git的密钥
$ ssh-add id_rsa_github
$ ssh-add id_rsa_gitee
测试
ssh -T git@github.com
ssh -T git@gitee.com
如何参与开源项目
fork项目到自己的git
浏览git上的开源项目,然后点击fork,这时就跳转到了你的账号下,此项目就是你的git仓库下的一个项目了
clone 代码到本地
# 克隆代码到本地
git clone https://gitee.com/xiaoxiaoyunlu/mano-mall.git
# 进入项目目录
cd mano-mall
添加原作者的仓库地址
git remote add upstream https://gitee.com/xiaoxiaoyunlu/mano-mall.git
查看远程:
$ git remote -v
origin https://gitee.com/自己的仓库名称/mano-mall.git (fetch)
origin https://gitee.com/自己的仓库名称/mano-mall.git (push)
upstream https://gitee.com/xiaoxiaoyunlu/mano-mall.git (fetch)
upstream https://gitee.com/xiaoxiaoyunlu/mano-mall.git (push)
创建开发分支
当然,你可以不创建开发分支,直接在自己的master
分支上修改,不过最好还是创建一个开发分支,便于维护和管理
git checkout -b dev_mall
然后就可以打开ieda
进行修改了
提交到自己的git
# 先获取一下原作者的,看看更新没有
git pull upstream
# 如果没有的话,那就直接提交,有的话,修改下代码在提交
git push -u origin master
申请提交代码到原项目
你对项目的修改已经push到了你的github下了,但是你要向原作者请求合并到原项目中,如果原作者审核后同意合并了,你的更新才能真正提交到原作者的远程仓库,也就意味着你是此项目的贡献者了。
-
点击
Pull requests
-
点击最右边的
New pull request
-
然后按照操作提交,等待原作者审核合并
使用Git常见问题
push error: src refspec master does not match any.
$ git push -u origin master
error: src refspec master does not match any.
error: failed to push some refs to 'https://gitee.com/xiaoxiaoyunlu/mano-mall.git'
引起该错误的原因是,目录中没有文件,空目录是不能提交上去的 ,可以先丢个README.md
git add README
git commit -m 'first commit'
git push origin master
push remote: You must verify your email address.
remote: You must verify your email address.
remote: See https://github.com/settings/emails.
fatal: unable to access 'https://gitee.com/xiaoxiaoyunlu/mano-mall.git/': The requested URL returned error: 403
很坑爹的问题,git界面上去验证一下邮箱就好了
push后不是项目,而是文件
如果是从网上别人仓库git clone
克隆下来的代码,修改后提交的话,必修删除.git
文件,然后重新初始化提交,否则就会出现提交也不报错,但是就是提交的是一个文件,而不是项目,点不进去
git clone RPC failed; curl 18 transfer closed with outstanding read data remaining
remote: Counting objects: 5148, done.
remote: Compressing objects: 100% (16/16), done.
error: RPC failed; curl 18 transfer closed with outstanding read data remaining
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed
发现是由于项目体积过大,所以先尝试增加git传输的项目大小:
git config --global http.postBuffer 1024288000
结果依然还是报错,尝试浅克隆成功,具体如下:
git clone https://gitee.com/xiaoxiaoyunlu/mano-mall.git --depth 1