git简介
| 1 | # 镜像站 | 
- 安装- windows:官网下载对应安装包
- Centos:yum -y install git
- Ubuntu:sudo apt-get install git
- 客户端界面
 
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 | ## 基于某个上游版本进行开发 | 
查看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可以显示更加短小的提交ID
- git 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,Windows重新安装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 | ## 完全丢弃本地修改,重置为远程分支的最新状态 | 
暂存工作区
| 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
 
| 1 | # 会生成 id_rsa.github.test 和 id_rsa.github.test.pub 文件 | 
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-还原,再与资源库同步更新别人修改后的该文件,再将自己的修改加上去,最后进行同步提交)
- 解决冲突后,再提交(先更新一下)
 
参考文章
