git简介
1 | # 单文件下载 |
git入门
git配置
全局配置
- 配置
1 | # 列出所有配置 |
以上操作其实是对git的根目录下.gitconfig(~/.gitconfig
,~
代表根目录,cat ~/.gitconfig
查看此文件)进行的操作,也可直接对这个文件进行修改
cat 文件路径名
查看某个文件,如:cat ~/.gitconfig(~
代表根目录)vi 文件名
打开某个文件进行编辑
- 点击键盘
insert
,进入vi编辑模式,开始编辑;- 点击
esc
退出编辑模式,进入到vi命令行模式;- 输入
:x
/ZZ
将刚刚修改的文件进行保存,退出编辑页面,回到初始命令行ls
查看当前目录结构,ls -A
可以显示隐藏的目录
项目配置
.git/config
文件
1 | # 分支信息 |
git config core.ignorecase false
配置项目大小写敏感
repository
创建repository(并关联远程仓库)
cd d:/git/demo/
进入到项目文件夹(可使用mkdir 文件夹名
在当前目录创建文件夹或者手动创建)- 此时git bash上显示
test@ST-008 MINGW64 /d/git/demo
(直接在demo目录右键-Git Bash Here
也是这个显示) - 如果直接点击桌面上的git图标进入命令行显示的是
test@ST-008 MINGW64 ~
- 创建之后,d:/git/demo/目录就是后面提到到 working 区(其实就是本地磁盘)
- 此时git bash上显示
git init
初始化项目,提示 Initialized empty Git repository in D:/git/demo/.git/- 此时就产生了后面提到的 staging 和 history 区
git add .
添加所有文件到本地索引git commit -am '初始化提交'
提交修改到本地仓库git remote add origin https://github.com/oldinaction/jekyll_demo.git
添加远程仓库地址,保存在origin变量中git push origin master
按照前一条命令中origin给定的git远程地址推送到远程仓库的master分支(容易和远程产生冲突)
- 克隆repository
git clone https://github.com/UserName/ProjectName
,这是利用https方式克隆,还有其他如git、ssh等方式(克隆后git会在当前目录新建一个文件夹为 “ProjectName” 的项目)git clone -b <remote branch> <remote address>
克隆远程仓库的某个分支/标签(如:git clone -b develop http://192.168.1.1/test.git
,此时本地分支名默认也为develop)git clone username@aezo.cn/xxx.git
指定用户名,用户名如果包含@
等特殊字符需要转转义,如@
对应%40
(私有仓库如果未指定用户名时:全局有指定用户名则使用全局,如果全局无则弹框输入)git clone username:password@aezo.cn/xxx.git
- 克隆远程仓库的某个文件夹
- 建立本地仓库
mkdir project_folder
cd project_folder
git init
git remote add -f origin <url>
git config core.sparsecheckout true
允许使用Sparse Checkout模式- 保存需要下载的文件夹名到
.git/info/sparse-checkout
文件中。如echo "src" >> .git/info/sparse-checkout
git pull origin master
拉取相应分支
- 建立本地仓库
- 多个远程仓库(同一代码提交到oschina和github)
1 | git remote add origin git@github.com:test1/test1.git # 推送到github |
分支
- 查看分支
git branch
查看本地分支(*
代表当前所处的分支)git branch -a
查看本地和运程所有分支
- 创建分支
git branch 分支名
创建一个新的分支。如果此分支和 master 是同一级分支(及在处于 master 时创建的分支),那么他们指向同一个 commit 对象git checkout -b <localBranchName>
创建一个本地分支并且换到此分支(是git branch 分支名
和git checkout 分支名
的合并命令)git checkout -b <localBranchName> <remotesBranchName>
相当于检出远程的某个分支到本地,远程分支名如origin/b1(使用git branch -a
查看时显示为remotes/origin/b1)git checkout -b <localBranchName> --track <remotesBranchName>
检出分支并创建本地分支与远程分支的追踪- 勿使用
git checkout 远程分支名
命令会是当前HEAD变为一个游离的HEAD(即现在HEAD指向的是一个没有分支名字的修订版本,游离于已知的所有分支之外,如HEAD detached at origin/b1
) git checkout -b test1 origin/develop
拉取远程develop分支
git push origin <branch>
创建远程分支
- 切换分支
git checkout 分支名
切换到此分支(Switched to branch ‘分支名’),此时 HEAD 指向此分支;并且本地磁盘(working 区)的内容会显示此分支的文件
- 合并分支
git merge 子分支名
将子分支名合并到当前分支(合并可能产生冲突,产生冲突后需要人为解决)
- 跟踪/关联分支
git branch --set-upstream-to=<remotesBranchName> <localBranchName>
- 必须先要有此本地分支。之后可以使用
git push/pull
直接对相应分支进行操作 git branch -vv
查看分支的关联关系
- 必须先要有此本地分支。之后可以使用
- 删除分支
git branch -d 分支名
删除此分支(只能删除除当前分支以外的分支;如果当前分支有一次提交,则需要将此分支合并到主分支之后再进行删除)- 删除远程分支:
git branch -r -d origin/branch-name
或者git push origin :branch-name
- 重命名分支:
git branch -m old-branch-name new-branch-name
- 在git中重命名远程分支,其实就是先删除远程分支,然后重命名本地分支,再重新提交一个远程分支
tag标签
1 | # 列举所有tag |
跟踪/提交/合并
- 跟踪/提交
1 | # 将 working 中此文件或者所有文件添加到 staging 区 |
- 合并
1 | ## merge |
丢弃/暂存/撤销/重置
- 丢弃
1 | # 丢弃本地修改:他会将文件从 working 区删掉(等同于没有修改) |
- 暂存和恢复暂存
1 | # 把所有没有提交的修改暂存到stash里面 |
- 撤销和重置
revert
是放弃指定提交的修改,但是会生成一次新的提交,需要填写提交注释,以前的历史记录都在reset
是指将HEAD指针指到指定提交,历史记录中不会出现放弃的提交记录
1 | # 参考:https://blog.csdn.net/QQxiaoqiang1573/article/details/68074847 |
- 撤销所有的提交(相当于初始化项目)
1 | # 参考: https://blog.csdn.net/icansoicrazy/article/details/128342811 |
删除文件
在用使用 git clean
前,强烈建议加上 -n 参数来先看看会删掉哪些文件,防止重要文件被误删
git clean -nf
查看删除文件git clean -f
删除 untracked files
git clean -nfd
git clean -fd
连 untracked 的目录也一起删掉
git clean -nxfd
git clean -xfd
连 gitignore 的untrack 文件/目录也一起删掉 (慎用,一般这个是用来删掉编译出来的文件用的)
git rm <file>
将此文件从 repository 中删除git rm --cached <file>
将此文件从 staging 区中删除,此时 working 区中还有git mv README.txt README.md
将 README.txt 文件重命名为 README.md(markdown格式)
与远程仓库同步
git fetch 远程仓库地址
下载远程仓库的变动到当前分支的历史区git pull 远程仓库地址
取回远程仓库的变化到当前分支的工作区git pull
获取本分支追踪的远程分支git pull origin develop
获取远程develop分支(使用git branch -a
查看时显示为remotes/origin/develop)git pull origin master:test
取回远程的master分支到本地test分支
git push 远程仓库地址
将本地仓库内容同步到远程仓库,回车后输入用户名和密码即可
同步两个远程仓库
1 | # 指定当前 fork 将要同步的上游远程仓库地址(upstream只是一个别名,可使用其他代替) |
查看git状态和文件差别
- 利用
git status
查看文件状态,git status -s
显示文件扼要信息- Git内部只有三个状态,分别是未修改unmodified、修改modified、暂存staged。对于没有加入Git控制的文件,可以视为第四种状态未跟踪untracked
- 提示 Untracked files 表示没有向 git 进行登记,需要增加到 git 进行版本控制(下面文件显示红色)。使用
git add <file>
/git add .
- 提示 Changes to be committed 表示文件被修改,等待提交(下面文件显示绿色)。使用
git commit -m '提交时的备注'
- 提示 nothing to commit, working directory clean 表示没有文件需要提交
- 运行
git status -s
命令,显示的标识位信息分别表示staging 和 working两个区A_
其中 A 表示 staging 中新加的文件,空格表示 working 没有变化(其中_
表示空格)_M
其中空格表示 staging 中没有改变,M 表示 working 做了修改MM
表示 staging 和 working 都发生了变化D_
表示 staging 中此文件被删除了R_
表示 staging 中此文件进行了重命名??
表示此文件没有被 git 进行版本控制
git status --untracked-files
以文件的形式展示(默认以文件夹)
- 利用
git diff
查看文件差别,git diff --stat
是对文件差别的扼要描述-红色字体
表示删除的+绿色字体
表示增加的git diff
默人对git status -s
的第二个标识位(working)进行详细描述;- 使用
git diff --staged
/git diff --cached
则是对第一个标识位(staging)进行详细描述; - 使用
git diff HEAD
则是对 history 区此文件的描述
- 注意事项
- git不监控文件权限属性变化
gitignore
.gitignore
文件创建和设置- git根目录运行命令:
touch .gitignore
- 使用 vi 编辑器进行文件配置
- git根目录运行命令:
- 配置语法 ^6
1 | # 表示此为注释,将被Git忽略 |
- 已经提交的文件(git已经管理了此文件,仓库已经存在此文件)无法忽略解决办法
- 先删除对应文件,提交版本,再将此文件加到.gitignore中,再次提交则不会出现
- 如果是未提交的文件,此时不管.gitignore文件是否提交,.gitignore文件都是生效的
- 删除.DS_Store文件,然后加入忽略
sudo find /project/demo -name ".DS_Store" -depth -exec rm {} \;
其他
查看日志和帮助
git help
查看帮助。[]
为可选,<>
为必输git log
查看提交日志,Ctrl+Z
退出查看git log -1
查看最近一条提交git log --oneline
可以显示更加短小的提交IDgit log --graph
显示何时出现了分支和合并等信息git log --pretty=raw
显示所有提交对象的parent属性git reflog
查看每个提交版本信息(排在上面的为最新版本)
git cat-file -p 哈希码(或简写)或者对象名
展示此对象的详细信息git cat-file -t 哈希码(或简写)
查看Git对象的类型,主要的git对象包括tree,commit,parent,和blob等- 如:
git cat-file -t HEAD
的结果是commit表示此HEAD指向一个commit 对象
- 如:
cat .git/HEAD
查看HEAD指向(当前分支)。如打印.git/refs/heads/master
cat .git/refs/heads/master
查看HEAD的哈希码(简写取前7位)git rev-parse HEAD
获取 HEAD 对象的哈希码
commit对象
- commit 对象中 parent 属性指向前一个 commit,tree 属性指向一个 tree 对象(此 tree 对象可以指向文件或者文件夹)
- HEAD 指向 master(只有一个分支的情况下),master 指向最新的 commit;HEAD~(或master~)表示前一个 commit;HEAD~2(或master~2)表示上上一个 commit,以此类推;- HEAD~2^ 表示 HEAD~2 的父提交(此时和HEAD~3是同一个对象)
- HEAD 的哈希码存放在
.git/refs/heads/xxx
文件中(当前处于xxx分支)
git凭证存储
- 官网凭证存储说明
git config --list
中credential.helper
即为凭证存储模式git config --global credential.helper store
设置凭证存储为store模式- 凭证存储模式
- manage 使用windows凭证管理(控制面板 - 用户管理 - 凭证管理,Git-2.15.1.2-64-bit默认)
- cache 凭证保存在内存中,默认15分钟有效,过期运行git命令则需要重新登录
- store 以明文形式保存在home目录磁盘。/home/xxx/.gitconfig(清除或修改)
- osxkeychain mac系统专属,加密后存放在磁盘
- 常见问题
remote: Repository not found
,重新安装credential-manager
git credential-manager uninstall
git credential-manager install
git免密码登录
- 法一:使用manage保存凭证(不适合同一台机器上使用多个git账号,就windows而言,这个凭据放在windows的凭据管理器中)
git config credential.helper manager
法二:使用SSH方式
ssh-keygen -C 'test-pc'
git客户端执行生成秘钥,会在用户家目录下的.ssh文件夹中生成2个名为id_rsa和id_rsa.pub的文件- 以github为例:Github - Setting - SSH and GPG keys - New SSH key - Name可随便标识,把id_rsa.pub公钥文件内容保存在Key中 (客户端一定要将私钥文件id_rsa保存到.ssh目录,普通的ssh登录客户端貌似无需私钥文件?)
git config --global user.name "git服务器用户名"
git config --global user.email "邮箱"
git remote set-url origin git@github.com:USERNAME/REPOSITORY.git
ssh -T git@github.com
测试是否可以正常登录,ssh -vT git@github.com
显示登录信息常见问题:
Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password)
,参考文章:https://blog.51cto.com/11975865/2308044,https://www.cnblogs.com/sloong/p/6132892.html。实际操作gitlab遇到的是另外一个问题,具体如下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# 1.一直提示以下内容
debug1: Next authentication method: gssapi-with-mic # 表示使用gssapi-with-mic进行验证
debug1: Unspecified GSS failure. Minor code may provide more information
No Kerberos credentials available (default cache: KEYRING:persistent:0)
debug1: Unspecified GSS failure. Minor code may provide more information
No Kerberos credentials available (default cache: KEYRING:persistent:0)
debug1: Next authentication method: publickey # 使用publickey进行验证
debug1: Offering RSA public key: /root/.ssh/id_rsa
debug1: Server accepts key: pkalg ssh-rsa blen 279
debug1: Trying private key: /root/.ssh/id_dsa
debug1: Trying private key: /root/.ssh/id_ecdsa
debug1: Trying private key: /root/.ssh/id_ed25519
debug1: No more authentication methods to try.
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
# 2.git客户端登录的是root用户,原本只存在文件/root/.ssh/id_rsa.pub,发现上面使用的是id_rsa,则仅仅将id_rsa.pub改成id_rsa文件(仍然是公钥文件)
Enter passphrase for key # 要求输入密码,但是生成秘钥对的时候并没有密码
# 3.直接使用原始生成的id_rsa秘钥文件,则将之前生成的秘钥文件也加入到此目录
Permissions 0644 for '/root/.ssh/id_rsa' are too open.
It is required that your private key files are NOT accessible by others.
# 4.提示上面文件开放权限太大,在git客户端设置`chmod 600 /root/.ssh/id_rsa`,可正常使用
通过ssh获取代码时,在命令行可以正常获取,在idea界面中无法拉取代码(idea的命令行可以)
- 设置idea中Git配置项的SSH executable=Native
常见业务场景
解决冲突
- 如下,
<<<<<<< HEAD
和=======
中间的是自己的代码,=======
和>>>>>>>
中间的是其他人修改的代码
1 | $ cat .eslintignore |
- 查看
1 | # 查看操作状态 |
暂存工作区
1 | # 备份当前的工作区的内容,从最近的一次提交中读取相关内容,让工作区保证和上次提交的内容一致。同时,将当前的工作区内容保存到Git栈中(比如有紧急Bug需要修复) |
处理Linux/Unix/MacOS文件格式的EOL
https://help.github.com/en/articles/configuring-git-to-handle-line-endings
大文件删除及管理
1 | git rev-list --objects --all \ |
- 基于bfg.jar清理
1 | ## bfg清理 |
Git通过命令行使用多个账户登录GitHub
- 使用~/.ssh/config文件解决
- https://zhuanlan.zhihu.com/p/521768041 无需设置ssh-agent
gitflow工作流
- 参考 ^5
git提交规范
1 | ## 提交格式 |
Github使用
- 镜像站
- emoji语法: https://gist.github.com/rxaviers/7360908
- 对于私有项目,通过https访问时不能通过密码验证,可通过github-cli验证
1 | # cli 使用手册: https://cli.github.com/manual/ |
更新fork项目/提交请求(
pull request
,简称PR
)- Github线上提交
New pull request
- 选择base repository
- 选择head repository
- 如果看不到仓库名可点击compare across forks
- 点击Create pull request
填写提交说明并确认- 表示将head提交到base。如果为更新fork项目,则base选择自己fork的仓库,head选择源仓库(此时可能需要点击
compare across forks
才能看到仓库名);如果是提交代码到源仓库,则base选择源仓库
- 表示将head提交到base。如果为更新fork项目,则base选择自己fork的仓库,head选择源仓库(此时可能需要点击
命令行提交(以更新fork项目为例)
1
2
3
4
5
6
7
8
9
10# 查看远程仓库信息
git remote -v
# 添加源仓库信息
git remote add upstream git@github.com:xxx/xxx.git
# 下载远程代码
git fetch upstream
# 将源仓库的upstream/master分支合并到当前分支
git merge upstream/master
# 推送到远程(fork的项目远程)
git push
- Github线上提交
gitee下fork项目同步
- 基于命令行模式 https://blog.csdn.net/weixin_53385000/article/details/117780266
- 基于界面 https://blog.csdn.net/luoyeyilin/article/details/108994031 (前提: 自己重新定义一个分支当成最新分支)
svn扩展
- 下载项目:检出
- 更新代码到SVN
- 项目右键(yitong)-Team-与资源库同步
- 选择模式:IncomingMode将别人提交的代码同步到本地;outcomingMode将本地修改的代码同步到SVN,Incoming/outcomingMode双向。选择后并没有触发更新
- 冲突:表示有两个或者多个人同时修改了一个文件。必须先解决冲突再进行更新。让两个人的代码共存:先备份自己修改后的那个文件,再将此文件还原到初始状态,再将SVN别人提交的代码同步到本地,最后将我修改过的代码加到此文件上。
- 同步代码到本地
- 选择IncomingMode
- 打开所有的树形结构,文件没有红色标示的则表示和本地文件没有冲突。选择没有冲突的文件-右键-更新
- 有冲突的先解决冲突。
- 提交代码到SVN
- 选择outcomingMode
- 打开所有的树形结构,文件没有红色标示的则表示和本地文件没有冲突。选择没有冲突的文件-右键-提交
- 有冲突的先解决冲突。(先备份该文件,再将冲突文件Team-还原,再与资源库同步更新别人修改后的该文件,再将自己的修改加上去,最后进行同步提交)
- 解决冲突后,再提交(先更新一下)
参考文章