git使用指南

09 Feb 2020 - Sindweller-ch

git指南

本文基于个人git使用经验总结而成,可供初学者上手参考,欢迎补充与指正! 下载安装config以及添加ssh等请自行搜索完成。

git仓库

本地 fork 上游
local origin upstream
基于本地仓库修改代码 自己fork的仓库,拥有修改权限,可以push本地代码 源仓库,一般没有修改权限,所以无法直接push;拥有最新版本的代码

本地仓库初始化相关命令

需求分析:

我要开始为开源社区做贡献了!

git初始化命令

新建本地目录,在该目录下进行如下操作:

已有项目远程仓库

  1. 下载代码
    git clone origin_ssh_url
  2. 添加与之关联的上游仓库(名字可以随意,建议命名为upstream)
    git remote add upstream upstream_ssh_url
    ok,到这里就把github里的项目挪到本地了,下一步是开发前的准备——更新/新建分支。

本地项目尚未上传

  1. 初始化本地git仓库
    git init
  2. 添加与之关联的fork仓库(名字可以随意,建议命名为origin)
    git remote add origin origin_ssh_url
  3. 确认关联仓库
    git remote -v

更新本地代码

需求分析:

  1. upstream仓库有更新,而自己fork的origin仓库和本地代码不会自动与之同步。
  2. 其他原因导致本地代码落后于upstream(或origin,极特殊情况)的代码

实际上,origin/master是不需要单独更新的,因为只要将local/master更新至upstream/master,就可以在本地master的基础上新建本地分支,基于最新代码进行修改。修改完成后再push至origin上。

git更新本地代码命令

  1. 拉取上游代码
    git fetch upstream git fetch upstream
  2. 同步本地分支 local/master -> upstream/master
    git rebase upstream/master
    git rebase upstream/master
  3. 此时使用git status查看状态
    git status
    会发现本地代码已经同步了上游的代码,领先了origin的代码,此时已经可以开始开发了。如果你非要让origin也同步: git push origin master
    接下来就可以进行开发了~

分支

需求分析:

  1. 需要开发多个独立的功能,并以pr的方式逐一提交。
  2. 需要保留master上的代码。

注:

分支同样分为本地(local)分支、origin分支、upstream分支。
一般在本地,与上游代码同步后,基于local/master新建本地分支,该分支中的代码继承master,且在该分支上的改动不会影响local/master中的代码。
建议开发时,尽量将不同分支上开发无互相依赖的不同功能,如在branch A上开发A功能,切换到branch B上开发B功能……
分支之间互不影响,但仍然要注意是否有依赖,否则会在合并时出现冲突。尽量使各功能的开发独立。

开发新功能时请记得切换回到master再新建分支!!

git分支常用命令

git checkout branch_name 切换至branch_name分支
git checkout -b new_branch 新建并切换至new_branch分支
git branch -a 查看所有分支(标记的为所在分支)
git branch -D branch_name 删除本地的branch_name分支(请不要直接在该分支上做这种过河拆桥的事情),该操作不会影响远程仓库的分支
git push origin :branch_namegit push origin --delete branch_name 删除远程分支——fork仓库的branch_name分支

提交本地代码

需求分析:

  1. 保存,防止电脑突然歇菜
  2. 暂存,以便之后放弃修改回退到该状态
  3. 开发完成,准备回馈上游社区

git提交命令

本地代码的提交分为三步:推到暂存区、添加提交内容描述、推到origin仓库的新分支上

  1. 建议先确认下修改内容,是不是在正确的分支上,因为如果搞错了,这里没有新修改的内容,是推不上去的
    git status
  2. 将本地修改推到暂存区
    git add -A-A的意思是全部)

    有许多网上教程在这一步写的是git add .,但该命令仅提交新文件(new)和被修改(modified)文件,不包括被删除(deleted)文件;git add -u表示将已跟踪文件中的修改和删除的文件添加到暂存区,不包括新增加的文件;-A则包括以上两种功能
    git add -i可以查看所有被所有修改过或已删除文件但没有提交的文件
    git add [<path>]可以指定添加文件或目录至暂存区

  3. 添加提交描述,这个commit会显示在仓库首页,即最近一次修改,请用简洁正常语句撰写,之前的所有commit也都会保留在github的仓库里,这样比较好看版本修改内容
    git commit -m "simple normal words"
  4. 推送至origin仓库新分支,建议跟本地分支同名
    git push origin new_branch
    然后就可以打开github网页,自己的仓库首页就会提醒你是否根据这个branch创建pr。

合并多个提交commit

需求分析:

在修改代码的过程中,我们在本地与origin仓库间可能存在着多次提交(commit),建议最终提交pr时,合并所有commit,保证该pr内仅包含一次提交。
尽管可以经由审查人员直接在merge时合并所有提交,但仍期望在pr中有着干净的提交记录,规范的pr可以反映出提交者的专业性。
以下命令同样适用于在已提交pr的情况下继续修改该分支代码,pr会自动与分支代码同步,通过使用git commit --amendgit push --force强制推送来保证只有一次commit记录

git合并多个提交命令

代码版本回退、合并

需求分析:

  1. 开发进行中,远程代码已更新,需要同步
  2. 放弃本地修改

git同步与合并命令

放弃本地修改

这里分三种修改阶段:

  1. 本地修改还没有使用git add命令提交至暂存区,使用:
    git checkout -- filepathname
    如果需要放弃所有的文件修改,可以使用git checkout .
  2. 本地修改已经由git add缓存:
    git reset HEAD filepathname重置,放弃指定文件的缓存,同样如果需要放弃所有缓存可以使用git reset HEAD .命令 此时本地修改还未完全消失,而是回到1.的状态,后续操作同上
  3. 已经用git commit提交了代码:
    git reset --hard HEAD^回退至上一次commit的状态
    git reset --hard commitid回退至任意commit状态(使用git log来查看git的commit历史,确定需要的commitID)

本地新建文件并没有加入到git的管理系统中,对于git来说是未知的(untracked files),如果放弃该文件,需要手动删除或使用: git clean -fd -n查看确认需要删除的文件
git clean -fd即可删除,其中-f表示文件-d表示目录。如果需要删除.gitignore中的文件,再加上-x;如果git submodule中也有需要删除的文件,加上-f变成git clean -dff
简单来说,删除git未跟踪文件可以这样执行:git clean -f

需要注意,在开发过程中,本地有可能自动生成.classpath等编译文件,这些在提交之前都需要用git clean -f清除

修改pr

直接修改对应的本地分支再git push --force origin xxx到origin对应分支就行了,pr会自动跟着branch的commit变

总结

综上,一套完整的开发、提交pr流程一般为:

  1. 新建本地目录,后续操作都需要在这个目录下进行
  2. 第一种情况:
    如果不存在远程仓库,即为还未上传的本地项目,在该目录下,git init初始化本地git仓库,这个命令用一次就行了,之后基于该仓库的操作请勿再使用init命令,人生没有重来,本地仓库也是
    git remote add origin ssh_url ssh_url是复制自己的仓库的ssh,将本地仓库关联该远程仓库
    git remote -v查看关联的仓库
    第二种情况:
    Github上已有项目远程仓库
    git clone ssh_url将代码下载下来,建议使用fork的origin仓库
    git remote add upstream ssh_url关联上游仓库
    git remote -v查看关联的仓库
    git fetch upstream+git rebase upstream/master开发之前一定要确保本地代码与上游同步,是最新的
  3. git checkout -b feature-A基于local/master,新建本地分支,开发功能A
  4. 开发ing……
  5. 开发完成后,git status看看修改的文件是不是那几个,确认后git add -A把所有的文件(代码)加入暂存区(或者git add [<path>]将指定文件或目录加入暂存区)
  6. git commit -m "the changes"添加一次提交,”“内填写本次提交概述
  7. git push origin branch_name将刚才加入暂存区的文件(代码)和提交内容推到origin的branch_name分支中
  8. 在github网页上,将origin/branch_name分支以pr形式提交给上游仓库
  9. 如若需要进行下一个功能的开发,记得切换回master分支,再新建本地feature-B分支进行B功能的开发

注意!

为国争光,禁用pull,从我做起。

git pull是一个非常强硬的命令,它会忽略一切细节并且可以把git fetchgit mergegit rebase等等的活儿都干了,中间没有出于安全考虑的确认
该命令还会将合并结果记录在新提交中,包含两个父提交的名称以及来自用户的描述更改的日志消息
虽然简单,但请勿使用git pull

流程链接

贡献流程