常用git命令

首先默认你已经知道什么是git,并且已经知道怎么安装git。本文只对常用 git 命令做讲解。

Git 全局设置:

git config --global user.name "information"
git config --global user.email "cdinformation@163.com"
  • 设置用户名和邮箱,用户名是你在commit的时候,显示的你的名字;
  • 邮箱,最好填写你的git账号邮箱,在github上,只有填写github账户邮箱,你的commit才会被计入你的贡献;
  • 这些配置的参数是保存在你的本地git仓库的config文件中的;/你的项目/.git/config (这个文件),其中.git是一个隐藏目录;

Git的基本操作流程:

  1. 从远端clone(克隆)或是pull(拉取)代码到本地;
  2. 对代码进行修改
  3. 将代码添加到本地仓库: 需要两部操作
    • step 1: git add {需要加入本地仓库的文件}
    • step 2: git commit -m "{对修改进行备注}"
  4. 将代码推送(push)到远端(origin)仓库

什么时候用clone?

  • 你是一个新员工,刚到公司,你本地电脑上还没有代码仓库,当你的领导分配给你git账号权限,并且给你远程仓库地址的时候,你就可以把远程仓库clone到本地;

什么时候用pull ?

  • 当你本地已经有 git 仓库的时候,就可以进入到 git 仓库那个目录,使用 git pull(拉取远程的代码)
    • 不是每次git pull 都能拉取新的代码到本地
    • 如果远程代码和本地代码是相同的,则会提示Already up to date.
    • 如果远程代码有改动,本地代码无改动,则会拉取远程最新代码到本地,并与本地代码合并
    • 如果远程代码和本地代码都有改动,则会检测代码是否有冲突(conflict),有冲突则需要先解决冲突,再pull,没有冲突则可以直接合并(merge)。
  • 在每次准备修改代码之前,都进行一次pull是一个好习惯
  • 在每次改完代码,做push之前,都做一次pull也一个好习惯

git 常用命令

 git init .                                  //初始化  
 git branch  dev                             //创建本地dev分支  
 git add newfile                             //提交新文件到暂存区  
 git commit -m 'add new file'                //提交到本地仓库  
 git remote add origin git@xx.com:demo.git   //添加远程仓库地址  
 git fetch origin  -p                        // 同步本地远程仓库镜像  
 git merge origin/dev                        // 合并远端dev分支  
 git push origin dev:dev                      //把本地dev 推送到远端  
 git branch feature-new origin/dev            // 基于远端dev 创建新分支 feature-new  
 git add newfeature.txt                      //提交新文件到暂存区  
 git commit -m ' finish new feature'             //提交到本地仓库  
 git checkout dev                                  // 切换回本地dev分支  
 git merge newfeature                        // 本地dev分钟 合并 newfeature分支  
 git brand -d newfeature                        // 合并完成,删除 newfeature 分支  
 git push origin :newfeature                 // 删除远端 newfeature 分支
 git fetch origin -p                         // 同步远端代码到本地  
 git merge origin/dev                        // 合并
 git push origin dev:dev                     // 推送本地dev到远端dev 

冲突解决

  • 当二个人同时更改了文件的某些部分,合并时将会出现冲突,此时,可找到另外一个人,仔细对比代码,手动删除不需要的代码,保留合理代码,然后提交 两个可能用到的命令
    git checkout --ours  conflict.php     //使用自己分支的代码,抛弃合并过来冲突
    git checkout --theirs conflict.php     //使用合并分支的代码,抛弃自己冲突这块更改的代码

什么是 commit ? 内容怎么写

  • commit 是备注本次修改的内容便于以后查看改动记录
  • git commit 回答三个问题 修改是什么?
    • 用什么方法修改的? 这些方法可能影响什么地方?
  • 每次commit只能包含一个改动
  • 每次commit必须单独写提交信息

查看git 记录

  • 通过git log查看最近的commit记录,在记录列表界面,输入q可退过查看记录列表
  • 通过git gui可打开GUI界面,在GUI面板上可以看所有提交记录

学会git status查看文件状态

  • 先用git status查看一下改动的文件状态;
    • 状态为红色,表示修改未添加到暂存区
    • 装态为绿色,表示文件已添加到暂存区

如果将暂存区的文件还原(把绿色的文件还原成红色)

  • 通过git reset命令可以将git status中显示"绿色"的文件还原成"红色"

如果修改了文件,如果撤销修改?

  • 先用git status查看一下文件名的颜色
  • 如果是“红色”:
    • 直接使用 git checkout -- {path/to/filename.php}
    • 把花括号中的名字换成你要还原的文件,需要指定具体路径下的文件
  • 如果是“绿色”:
    • 绿色的文件,需要先用git reset还原成红色,再使用git checkout -- 文件名
  • 如果即没有红色,也没有绿色——已经commit了,咋办?
    • 那只能版本回滚了,每个commit都会产生一个commit编号,你可以把这个编号理解为一个版本号,如果当前修改的代码commit了,那么回滚到上一个commit就可以了
    • 需要注意的是,回滚到上一个commit之后,当前commit的所有修改过的文件都会被还原,所以版本回滚需谨慎!

如果进行版本回滚?

  • 命令很简单git reset --hard 版本号
  • 版本号从哪里来?
    • 可以在git log中查看,也可以通过git gui查看

通过git log查看commit 版本号

wenqidongdeMacBook-Pro:kaleoz-api wenqidong$ git log
commit 8b1acd38a0e609d706ff38d74055c3f47099c936 (HEAD -> master, origin/ucp-statistics, origin/master, origin/HEAD, ucp-statistics)
Author: wenqidong <wqd1688@gmail.com>
Date:   Tue Jan 29 14:02:19 2019 +0800

    新增币种时,接收name_zh参数,返回列表按id倒序

commit b2214d961dd63fb5683fc6a760e0311d2c1c1360
Author: wenqidong <wqd1688@gmail.com>
Date:   Mon Jan 28 15:09:11 2019 +0800

    部分退款,中间账户变动从买家/订单币中的中间账户变动

commit 98b00e84968c0ee719ec8b61cf15bf8101c98741
Author: wenqidong <wqd1688@gmail.com>
Date:   Mon Jan 28 14:08:46 2019 +0800

    fix

commit b031e4422e067d64a581b9050328e932803fc863
Author: wenqidong <wqd1688@gmail.com>
Date:   Mon Jan 28 11:52:30 2019 +0800

    新增币种时自动创建SystemSetting和IntermediateUser

通过tag发布版本

  • 本地Tag操作

    • 项目开发完了可以发布第一个版本了,打个标签(Tag),tag可以取为v1.0表示1.0版本;
      git tag -a v1.0 -m "第一个版本发布"
    • 默认的标签将打在最新的commit上。
    • 查看打了哪些标签使用
      git tag
    • 查看某个标签的信息用
      git show v1.0
    • 如果标签打错可以使用以下命令删除:
      git tag -d v1.0
  • 远程Tag管理

    • 我想要把v1.0推送到远程,
      git push origin v1.0
    • 把所有的标签一次推送到远程更爽,
      git push origin --tags
    • 删除远程的标签,你可以到github上删除,也可以,
    • 先删除本地的
      git tag -d v1.0
    • 删除远程的
      git push origin :refs/tags/v1.0

git 分支模型

git branch

git 不那么常用的操作

怎样让 git 只更新一个文件?

我们知道git的远端和本地都是一个仓库,当我们使用git pull的时候,会把远端最新的代码拉到本地,并覆盖掉本地代码库和工作拷贝;如果远端代码修改了3个文件,有没有办法只更新一个文件到本地仓库呢? 答案当然是有的。 具体的操作需要用到下面两个命令:

git fetch
git checkout origin/master -- path/to/file

理解 git fetch 的四种用法及与之相关的文件

  1. git fetch →→ 这将更新git remote 中所有的远程repo 所包含分支的最新commit-id, 将其记录到 .git/FETCH_HEAD文件中

  2. git fetch remote_repo →→ 这将更新名称为remote_repo 的远程repo上的所有branch的最新commit-id,将其记录。

  3. git fetch remote_repo remote_branch_name →→ 这将这将更新名称为remote_repo 的远程repo上的分支: remote_branch_name

  4. git fetch remote_repo remote_branch_name:local_branch_name →→ 这将这将更新名称为remote_repo 的远程repo上的分支: remote_branch_name ,并在本地创建local_branch_name 本地分支保存远端分支的所有数据。

FETCH_HEAD: 是一个版本链接,记录在本地的一个文件中,指向着目前已经从远程仓库取下来的分支的末端版本。下面是一个测试仓库的FETCH_HEAD

wenqidongdeMBP:doctor wenqidong$ cd .git
wenqidongdeMBP:.git wenqidong$ ls
COMMIT_EDITMSG  ORIG_HEAD   gitk.cache  info        packed-refs
FETCH_HEAD  config      hooks       logs        refs
HEAD        description index       objects
wenqidongdeMBP:.git wenqidong$ cat FETCH_HEAD 
783cd11f2bcf929a8c50e3532dfb20b967290a5f        branch 'feature-wqd' of https://gitee.com/cdinfo/doctor
6fbf9d7fb9a69e8585b18ba375040551f285ce3d    not-for-merge   branch 'feature-wechat' of https://gitee.com/cdinfo/doctor
783cd11f2bcf929a8c50e3532dfb20b967290a5f    not-for-merge   branch 'master' of https://gitee.com/cdinfo/doctor

通过git fetch 更新本地仓库的方式

//方法一
$ git fetch origin master //从远程的origin仓库的master分支下载代码到本地的origin master
$ git log -p master.. origin/master//比较本地的仓库和远程参考的区别
$ git merge origin/master//把远程下载下来的代码合并到本地仓库,远程的和本地的合并

//方法二
$ git fetch origin master:temp //从远程的origin仓库的master分支下载到本地并新建一个分支temp
$ git diff temp//比较master分支和temp分支的不同
$ git merge temp//合并temp分支到master分支
$ git branch -d temp//删除temp

关于版本回滚,除了git reset, 还有一个git revert,区分一下什么时候适合用git reset, 什么时候适合用git revert?

1、git reset

没有push,这种情况发生在你的本地代码仓库,可能你add ,commit 以后发现代码有点问题.

首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交commit_id(79f673d631b08907496ce792f429e1f00da25b73),上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。

HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard 79f673d631b08907496ce792f429e1f00da25b73。

穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。

要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。

2、git revert

已经push,对于已经把代码push到线上仓库,你回退本地代码其实也想同时回退线上代码,回滚到某个指定的版本,线上,线下代码保持一致.你要用到下面的命令

git revert用一个新提交来消除一个历史提交所做的任何修改.

revert 之后你的本地代码会回滚到指定的历史版本,这时你再 git push 既可以把线上的代码更新.(这里不会像reset造成冲突的问题)

revert 使用,需要先找到你想回滚版本唯一的commit标识代码,可以用 git log 或者在adgit搭建的web环境历史提交记录里查看.

git revert c011eb3c20ba6fb38cc94fe5a8dda366a3990c61

3、两者区别

git revert是用一次新的commit来回滚之前的commit,git reset是直接删除指定的commit看似达到的效果是一样的,其实完全不同.

第一:上面我们说的如果你已经push到线上代码库, reset 删除指定commit以后,你git push可能导致一大堆冲突(或git push -f强制推送).但是revert 并不会.

第二:如果在日后现有分支和历史分支需要合并的时候,reset 恢复部分的代码依然会出现在历史分支里.但是revert 方向提交的commit 并不会出现在历史分支里.

第三:reset 是在正常的commit历史中,删除了指定的commit,这时 HEAD 是向后移动了,而 revert 是在正常的commit历史中再commit一次,只不过是反向提交,他的 HEAD 是一直向前的.