安装

官网: [https://git-scm.com/]

mac 使用dmp包

centos: sudo yum install git

ubuntu: sudo apt install git

配置user信息

git config —global user.name “your username”

git config —global user.email “your email”

config 的三个作 域

git config —local #local只对仓库有效

git config —globa l#global对登录 户所有仓库有效

git config —system #system对系统的所有 户有效

显示 config 的配置,加 —list

git config —local —list

git config —system —list

git config —global —list

清除—unset

git config —unset —local user.name

local > global > system

git 命令

创建空的 commit

$ git commit —allow-empty -m ‘Initial’

git工作区概念

工作目录,暂存区 ,版本历史

git add 后 加入暂存区,

git commit 后加入版本历史

git reset —hard #清楚暂存区,还原到当前版本

git mv “oldname” “newname” #修改文件或目录

git log

git log —oneline #一行展示

git log —online —all #所有分支

git log -n “number” #展示number次数

git log —online —all —graph -n 5 #图形化展示所有版本最近5次 简化展示

git 工作目录

1.git/HEAD #内容是 当前工作版本

1$cat .git/HEAD    
2ref: refs/heads/master
  1. .git/config #配置信息可以通过修改文件来改配置

  2. .git/refs

    1heads     #本地分支
    2remotes  #远程分支
    3stash    
    4tags        #标签
    
1cd /Users/maozhongyu/code/huan/.git/refs/heads
2$ls -al
3-rw-r—r— 1 maozhongyu staff 41 4 12 10:44 fix_fix
4-rw-r—r— 1 maozhongyu staff 41 4 1 10:17 fix_mao
5-rw-r—r— 1 maozhongyu staff 41 4 8 16:53 master
6drwxr-xr-x 2 maozhongyu staff 68 12 28 13:54 origin
7-rw-r—r— 1 maozhongyu staff 41 4 11 11:49 temp_fix

$ cat master #里面内容是 commit-id

$ git cat-file -t “commit-id” #查看是什么类型对象

4.objects 里面存了 commit blog tree 对象

commit 和 blob 和 tree 的关系

git cat-file -p commit-id

1  cr-mao:huan$git cat-file -p 8c84201dff145     //8c84201dff145 当前commit-id
2   tree c9676e3b85877779d101701c891525d7ba1db184
3   parent e856d8342b6f9f6d7a69e4e1ecb430bc3b881c72
4   author maozhongyu <595106153@qq.com> 1555037045 +0800
5   committer maozhongyu <595106153@qq.com> 1555037052 +0800

tree 其实代表是目录,

parent 上一次提交commit

git cat-file -p c9676e3b8587

 1cr-mao:huan$git cat-file -p c9676e3b8587
 2   100644 blob 9bc41ba4a2ce81c452eae40ae084eb3782009c19    .env.example
 3   100644 blob 3ff53fc94cfee8faec3594871d4ad872278c86a8    .env.job
 4   100644 blob b1440a4d4d22546defe352ba5124a660dc31d06c    .env.online
 5   100644 blob a37453b0a389da334dee050dd32b40f547a7661d    .env.testing
 6   100644 blob a8763f8ef5f3ca507073252f6815171c00b47074    .gitattributes
 7   100644 blob 7cfc7e6fa61fd568f44956fa2bdf6943900510f5    .gitignore
 8   100644 blob 5ff3897fc37aacb4cd96268264bf5c409d3be49f    Envoy.blade.php
 9   100644 blob 2dba3d2195154730cda614ac077d2e9ac90ca31d    Makefile
10   100644 blob 663a8fe7847f97b32edd761e8f8f5152e4da513d    README.md
11   040000 tree 7211053639482a1891b650de51efb2691e56f806    app
12   #再次执行
13   git cat-file -p 9bc41ba4a2  //文件内容
14   git cat-file -p 721105363948   //查看app树的内容

分离头指针 (checkout 没有基于某个branch 而是某个commit-id) 注意

1.git checkout commit-id //commit-id xxxx

2.然后直接开发,再commit //commit-id 3dackdkd2

3.git checkout 某个branch ,git提示 git branch branch_name 3dackdkd2 //基于commit-id 3dackdkd2 创建分支

git checkout -b new_branch branch_name #不写当前分支

HEAD关键词

当前指向当前 commit

cat .git/HEAD

1    refs/heads/fix_fix

cat .git/refs/heads/fix_fix #里面是commit-id

HEAD^ = HEAD~ #上一个commit

HEAD^^ = HEAD~~ #上上个commit

删除分支

1git branch -d branch_name
2git branch -D branch_name

修改最新的commit注释

git commit —amend

修改老旧的commit 注释

git rebase -i 想要变更的上一个commit_id img

怎么把多个commit整合成一个

git rebase -i commit-id # 你想开始整合多父提交

上图的 s,squash 合并到上次提交

怎么把间隔的几个commit 整合成一个

git rebase -i commit-id

里面的行可以上下移动 ,其他和上面操作一样

暂存区和HEAD之间的差异

git diff —cached //git add 后 就是暂存区

暂存区和工作区之间的差异

git diff file_name | git diff — file_name

如何让暂存区和HEAD 一样

git reset HEAD

部分文件恢复:git reset HEAD — file_name

如何让工作区的内容恢复为暂存区的内容

git checkout — file_name

取消最近的几次提交

git reset —hard commit-id

查看不同提交文件的差异

git diff commit-id1 commit-id2 — file_name

删除文件

git rm file_name

禁止向集成分支执行git push -f

1git reset old-commit-id
2git push -f //远程old-commit-id后的提交都会消失

禁止向集成分支执行改变历史

其他同事 会遇到no-fast-forward

gitlab 安装

1docker load < gitlab-ce-image.tar
 1$ docker run -d -p 4430:443 -p 800:80 -p 220:22 --name mygitlab --restart always -v \
 2/Users/mac/code/gitlab/etc:/etc/gitlab -v \
 3/Users/mac/code/gitlab/log:/var/log/gitlab -v \
 4/Users/mac/code/gitlab/data:/var/opt/gitlab gitlab/gitlab-ce
 5
 6
 7
 8sudo docker run --detach \
 9    --hostname mygitlab.com \
10    --publish 443:443 --publish 80:80 --publish 22:22 \
11    --name gitlab \
12    --restart always \
13    --volume /srv/gitlab/config:/etc/gitlab \
14    --volume /srv/gitlab/logs:/var/log/gitlab \
15    --volume /srv/gitlab/data:/var/opt/gitlab \
16    gitlab/gitlab-ce:latest

https://www.cnblogs.com/floodwater/p/10138265.htmls

这东西很迟内存,cpu 。

git flow

master,develop 分支 (必须有这2个) 也可以有realse,hotfix 分支, 工作者都基于develop分支创建新分支开发代码

大概就是这种流程

还有其他git工作流就是提pr合master,非常简单实用

GIT远程仓库代码回退

提交错误版本到远程公共仓库如何回退(这种方法适合几个人团队)

假设远程版本库dev分支的提交顺序是

B1 A2 A1

其中A1/A2是A程序员的提交,B1是B程序员的提交,其他人的本地分支也已经同步到最新状态。这时候A程序员发现A2的提交有错误需要回退到A1版本,那么A使用reset命令回滚到A1版本然后同步远程仓库到A1,理想状态下其他人一拉远程仓库就ok了,但是实际上由于其他人的本地仓库比远程仓库领先两个版本,所以他是不能回退的,你看到的是如下提示。

1$ git status
2On branch master
3Your branch is ahead of 'origin/dev' by 2 commits.
4  (use "git push" to publish your local commits)
5nothing to commit, working directory clean12345

那么这时候该怎么办?这时候需要A在协作群里大喊一声我的版本回退到A1了,A2以后的版本就要重新提交了!然而某个不靠谱队友看到本地仓库领先远程仓库2个版本,想当然的直接push推送,那么你的远程仓库dev分支又变回了

1B1 
2A2 
3A1

于是A程序员做的工作就白费了,然后一群人一头雾水的发现A2版本又又又出来了。 那么正确的做法是怎么样的呢?B队友的正确做法是硬回滚到B1提交的位置,然后拉取临时分支,这时候这个临时分支就不会包含A2提交的内容,然后将本地分支切到A1的位置,然后在这个点重新合并临时分支的内容。 A程序员回滚操作

1git reset --hard A1  //本地回退到A1版本git push -f origin dev //强制推送到远程仓库的 dev分支12

远程仓库版本变成如下

1A1

B程序员拉取临时分支回退并合并临时分支操作

 1git checkout dev      //切回工作分支
 2git reflog            //查看B1版本id
 3git reset --hard B1   //回滚到B1版本
 4git checkout -b devb1 //拉取分支
 5git log               //检查临时分支提交日志
 6git checkout dev      //切回工作分支
 7git reset --hard A1   //回滚到A1版本
 8git reset --hard origin/dev //回滚到远程dev分支头并保持一致,这时候已经完全回滚到A1版本了
 9git merge devb1             //合并临时分支版本
10git push origin dev         //推送到远程仓库dev分支12345678910

远程仓库分支提交变成如下情况

1B1
2A1

同理,如果所有人都被覆盖了代码的情况下都需要如上操作。

特别注意

在这里你是不是觉得已经掌握远程回滚的方法?但是实际上回滚还是需要条件的,那就是所有人提交的时候是需要保留分支信息的,如果没有分支信息每个人就回滚不到上一个“自己”的版本,我们有个开发组由于组长的个人爱好把分支树清理的特别干净,直到有一天有位仁兄错误提交代码了,回滚远程仓库以后没有通知其他人…………

不按正常套路的出牌方法

如果错误提交以后经过好多次新提交才发现,而且组员对回滚操作不熟悉的话,另外如果全体成员他们每个人都有备份都觉得直接回滚比较快的情况下简单粗暴的方法是可以重新建立一个新仓库,然后把正确的代码重新拷贝到新目录以后将代码提交到新仓库就可以,有问题直接修改少量代码就可以了。

另外实现方式 git revert 应该撤销的commid

bug 分支 git stash

 1并不是你不想提交,而是工作只进行到一半,还没法提交,预计完成还需1天时间。但是,
 2 必须在两个小时内修复该bug,怎么办?
 3幸好,Git还提供了一个stash功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作:
 4正在dev 分支上写代码 ,突然来了个bug 要修复
 5# git stash
 6Saved working directory and index state WIP on dev: f52c633 add merge
 7# git checkout master
 8# git checkout -b issue-101
 9   一顿操作后
10#git checkout master
11#git merge -m "merged bug gixx 101" issue-101
12#git checkout dev
13#git stash list
14// 工作现场还在,Git把stash内容存在某个地方了,但是需要恢复一下,有两个办法:
15一是用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除;
16另一种方式是用git stash pop,恢复的同时把stash内容也删了
17#git stash pop  
18再用git stash list查看,就看不到任何stash内容了:
19# git stash list
20你可以多次stash,恢复的时候,先用git stash list查看,然后恢复指定的stash,用命令:
21# git stash apply stash@{0}

标签

 1命令git tag <tagname>用于新建一个标签,默认为HEAD,也可以指定一个commit id;
 2#git tag  v0.8 xxxxx
 3#git show v0.8   // v0.8 为 tagname
 4还可以创建带有说明的标签,用-a指定标签名,-m指定说明文字:
 5命令git tag -a <tagname> -m "blablabla..."    commitid   可以指定标签信息;
 6#git tag -a v0.1 -m "version 0.1 released" 1094adb
 7命令git tag可以查看所有标签。
 8命令git push origin <tagname>可以推送一个本地标签;
 9命令git push origin --tags可以推送全部未推送过的本地标签;
10命令git tag -d <tagname>可以删除一个本地标签;
11命令git push origin :refs/tags/<tagname>可以删除一个远程标签。

配置别名

1当然还有别的命令可以简写,很多人都用co表示checkout,ci表示commit,br表示branch:
2$ git config --global alias.co checkout
3$ git config --global alias.ci commit
4$ git config --global alias.br branch
5--global参数是全局参数,也就是这些命令在这台电脑的所有Git仓库下都有用。
6git config --global alias.lg 
7"log --color --graph --pretty
8=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

其他

  • 有新的需求。 把你的分支 rebase master 后 。 那你的分支已经有了master 的代码了。 你checkout -b一个新的分支, 把这个新分支rebase 你们的开发分支,把代码合进去开发分支。 那以后这个开发分支rebase master 就很少会有冲突了 。
  • 新增ignore项,如果已在仓库中,需要git rm 才能生效
  • .gitignore 中**代表多级目录