玩转Git三剑客

玩转Git三剑客

  • 第一章:Git基础
    • 0.怎么看git xxxx --help
    • 1.基本配置
      • 1.2
        • 1.2.1 检查 ssh是否能正常连上gitlab
        • 1.2.2 权限太开放的问题
        • 1.2.3 查看ssh的日志
    • 2.Git 基本命令
      • 2.1建 Git 仓库
      • 2.2往仓库⾥添加⽂件
      • 2.2git的重命名
      • 2.3git reset
      • 2.4git diff
      • 2.5git stash
      • 2.6patch
        • 2.6.1diff
        • 2.6.2format-patch
        • 2.6.3应用diff/patch
      • 2.7git checkout
        • 创建并切换
      • 2.8gitignore
      • 2.9git alias
      • 2.10git reflog
      • 2.11git clean
      • 2.12git clone
      • 2.13git branch
      • 2.14git log
      • 12.14.1git show
      • 2.12git rebase
        • 2.12.1 merge vs rebase
          • git merge,同一个冲突解决过了,再合并,会再冲突吗?
      • 2.13备份仓库
      • 2.14git cherry pick
      • 2.15git difftool
      • 2.16git prune
      • 将已有的项目添加到远端
      • 2.17git revert
      • 2.100git submodule
      • 2.101 git hook
        • 2.101.1 hook在mac上不生效的问题
      • 2.102 git checkout vs git reset
    • 3.Git 探秘
  • 第三章:Git与GitHub简单同步
    • 1.注册一个GitHub账号
    • 2.配置公私钥
    • 3.在GitHub上创建个人仓库
    • 4.把本地仓库同步到GitHub
  • 第四章:Git多人单分支集成协作时的常见场景
    • 1.不同人修改了不同文件如何处理?
    • 2.不同人修改了同文件的不同区域如何处理?
    • 3.不同人修改了同文件的同一区域如何处理?
    • 4.同时变更了文件名和文件内容如何处理?
    • 5.把同一文件改成了不同的文件名如何处理?
  • 第五章:Git集成使用禁忌 (2讲)
    • 1.禁止向集成分支执行push -f操作
    • 2.禁止向集成分支执行变更历史的操作
  • 其它
    • 1批量clone
    • git-game
    • learn git branching

课程: 玩转Git三剑客.
课件: 课件pdf.
Git官方参考文档: Git Book.
Git官方本地文档:file:///D:/Program%20Files/Git/mingw64/share/doc/git-doc/(如file:///D:/Program%20Files/Git/mingw64/share/doc/git-doc/git-clone.html)

第一章:Git基础

0.怎么看git xxxx --help

如git clone --help

git clone [--template=<template_directory>]
	  [-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror]
	  [-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>]
	  [--dissociate] [--separate-git-dir <git dir>]
	  [--depth <depth>] [--[no-]single-branch] [--no-tags]
	  [--recurse-submodules[=<pathspec>]] [--[no-]shallow-submodules]
	  [--jobs <n>] [--] <repository> [<directory>]

[]代表可选
<>代表必需
上例中,最简单的命令为:git clone repository,如git clone [email protected]:pjgggg/pjgggg-client.git,
如果要加可选的,如[ – depth < depth >],则加了–depth,则要加他的参数深度,如git clone --depth 1 [email protected]:pjgggg/pjgggg-client.git,表示只克隆深度为一层。

1.基本配置


$ git --version
git version 2.19.0

$ git config --global user.name ‘your_name’
$ git config --global user.email ‘[email protected]

config 的三个作⽤域,缺省等同于 local

$ git config --local
$ git config --global
$ git config --system

local只对仓库有效
global对登录⽤户所有仓库有效
system对系统的所有⽤户有效


显示 config 的配置,加 --list

$ git config --list --local
$ git config --list --global
$ git config --list --system

清除,–unset

$ git config --unset --local user.name
$ git config --unset --global user.name
$ git config --unset --system user.name 

优先级
local > global > system

几个常用的设置
git config --global merge.ours.driver true
git config --global merge.ff no
git config --global pull.rebase true
git config --global rebase.autostash true


1.2

1.2.1 检查 ssh是否能正常连上gitlab

ssh

ssh [email protected]

如果密钥对设置好了,会有类似这样的提示

PTY allocation request failed on channel 0
Welcome to GitLab, @zhangjiequan!
Connection to gitlab.bbbb closed.

Win10下会提示,有水友提出各种解决办法,可以一试。

Bad owner or permissions on C:\\Users\\zhangjiequan/.ssh/config

1.2.2 权限太开放的问题

权限太开放问题
类似以下提示:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/Users/baioo/.ssh/id_rsa' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "/Users/baioo/.ssh/id_rsa": bad permissions

用ls -l查看,发现id_rsa的权限不对

ls -l 
-rw-r--r--  1 baioo  staff  1675  3 25 14:20 id_rsa
-rw-r--r--  1 baioo  staff   398  3 25 14:20 id_rsa.pub
-rw-r--r--  1 baioo  staff   369  3 25 14:20 known_hosts
drwxr-xr-x  5 baioo  staff   160  3 25 12:06 leipeng
drwxr-xr-x  5 baioo  staff   160  3 25 14:20 qiweiqi
drwxr-xr-x  8 baioo  staff   256  3 25 14:22 zhangjiequan

改成,600,即只有所有者有读和写的权限

chmod 600 id_rsa

再检查权限,发现正常了,也可以通过ssh的使用条件验证了

-rw-------  1 baioo  staff  1679  3  2  2018 id_rsa
-rwxr-xr-x  1 baioo  staff   403  3  2  2018 id_rsa.pub
-rw-r--r--  1 baioo  staff   182  3 25 13:01 known_hosts
drwxr-xr-x  5 baioo  staff   160  3 25 12:06 leipeng
drwxr-xr-x  5 baioo  staff   160  3 25 14:20 qiweiqi
drwxr-xr-x  8 baioo  staff   256  3 25 14:22 zhangjiequan

1.2.3 查看ssh的日志

ssh -vvvT [email protected]

GIT_TRACE=1 GIT_SSH_COMMAND=“ssh -vvv” git clone [email protected]:zhangjiequan/refreshporjects.git

2.Git 基本命令

2.1建 Git 仓库

两种⽅式:

  1. ⽤ Git 之前已经有项⽬代码
$ cd 项⽬代码所在的⽂件夹
$ git init 
  1. ⽤ Git 之前还没有项⽬代码
$ cd 某个⽂件夹
$ git init your_project #会在当前路径下创建和项⽬名称同名的⽂件夹
$ cd your_project 

2.2往仓库⾥添加⽂件

$ git add .
$ git commit -m "test add all" 
$ git commit -am "add 和 commit 二合一" 
$ git commit --amend #改最近一次提交的msg,amend修正
$ git commit --allow-empty -m "empty commit" 空提交

2.2git的重命名

git mv

$ git mv file_from file_to #将file_from重命名为file_to,并加入暂存区
#以上一条操作,等于以下组操作
#组1
$ mv file_from file_to
$ git add file_to
$ git rm file_from
#组2
$ mv file_from file_to
$ git add .
#组3
$ mv file_from file_to
$ git add file_to
$ git add file_from

注意,组1和组3中,分别对file_from进行git rm和git add,效果是一样的.所以,怎么理解git rm??git rm

2.3git reset

git reset --hard #什么都不管,直接还原到指定commit,不写则还原到HEAD
git reset --soft #??soft和mix的区别
git reset --mix  #??soft和mix的区别
git reset --hard HEAD~1 #指定commit,为Head的前一个commit
git reset --hard commitId#指定commitId
git reset <file> #暂存区的东东unstaged到工作区<指定文件> ,默认是mix

2.4git diff

git diff #工作区与暂存区的差别
git diff --cached #暂存区与HEAD的差别
git diff HEAD #工作区和HEAD的差别
git diff --cached --raw #"以原始格式生成差异",个人理解是“一行信息版”
git diff --cached --compact-summary #简要版
git diff commitId1 commitId2 #对比两个commiId/branchName,commitId2比commitId1多/少了什么
git diff commitId1 commitId2 -- file #指定文件的差异【vs code对比指定文件没反应?PowerShell/Cmder可以正常diff】

2.5git stash

$ git stash #默认信息
$ git stash save message_to_type #自定义信息
$ git stash list #列出来
$ git stash pop 1 #弹出并应用第1个
$ git stash apply 1 #应用第1个
$ git stash drop 0 #删除第0个,也可以写成git stash drop stash@{0}

2.6patch

Git 打补丁-- patch 和 diff 的使用(详细)

2.6.1diff

用git diff生成的UNIX标准补丁.diff文件, .diff文件只是记录文件改变的内容,不带有commit记录信息,多个commit可以合并成一个diff文件。

$ #git diff  【commit sha1 id】 【commit sha1 id】 >  【diff文件名】
$ git diff  2a2fb453992  89aebfcc > patch.diff

2.6.2format-patch

用git format-patch生成的Git专用.patch 文件,.patch文件带有记录文件改变的内容,也带有commit记录信息,每个commit对应一个patch文件。

$ #*某次提交(含)之前的几次提交:
$ #git format-patch 【commit sha1 id】-n
$ git format-patch  2a2fb4539925bfa4a141fe492d9828d030f7c8a8 -2
$ #*某个提交的patch:
$ #git format-patch 【commit sha1 id】 -1
$ git format-patch  2a2fb4539925bfa4a141fe492d9828d030f7c8a8 -1
$ #*某两次提交之间的所有patch:
$ #git format-patch 【commit sha1 id】..【commit sha1 id】 
$ git format-patch  2a2fb4539..89aebfcc7

2.6.3应用diff/patch

检查patch/diff是否能正常打入:

git apply --check 【path/to/xxx.patch】
git apply --check 【path/to/xxx.diff】

打入patch/diff:

git apply 【path/to/xxx.patch】
git apply 【path/to/xxx.diff】

2.7git checkout

git branch -av
#1、新建本地分支release/hotfix-1
#2、release/hotfix-1分支跟踪origin(远端)的release/hotfix-1
#3切换到本地分支release/hotfix-1
git checkout -b release/hotfix-1 origin/release/hotfix-1 
#git push    
git push origin release/hotfix-1 #简写为git push

git checkout . #丢弃工作区所有的文件,使之和暂存区一样
git cehckout file #丢弃指定文件,使之和暂存区一样

创建并切换

创建并切换到iss53这个分支:

$ git checkout -b iss53

上面一条命令是下面两条命令的简写:

$ git branch iss53#创建
$ git checkout iss53#切换

2.8gitignore

github提供的各种流程框架的 ignore参考.
.gitignore书写格式是 glob,很多编程语言和配置都会使用 glob 来模糊匹配文件名和文件夹。
一个git工程的可以有多个.gitignore文件,分别管自己的文件夹。

2.9git alias

Git 基础 - Git 别名.

git config --global alias.st status
[alias]
	st = status
	co = checkout
	ci = commit
	br = branch
	unstage = reset HEAD
	lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
	rsh = reset --hard

2.10git reflog

“危险”操作的后悔药

2.11git clean

git clean -fdx #删除得干干净净,慎用!!

-d 删除未跟踪的目录和未跟踪的文件。如果一个未跟踪的目录是另一个不同的 Git 库,默认 将不会把它删除。如果你想删除这个目录,可以使用 -f
-f , --force 如果 Git 配置中 clean.requireForce 没有设置为 false,git clean 将拒绝执行。除 非是使用 -f -n -i
-n , --dry-run 仅仅显示将被删除的文件,不会真正的删除。强烈建议clean前,加入,先看一下要删除什么,如git clean -nd
-x 不使用 .gitignore(每个目录)和 $GIT_DIR/info/exclude 的标准忽略规则,但仍然使用使用 -e 选项给出的忽略规则。这允许删除所有未跟踪的文件,包括构建产品。 这可以使用(可能与 git reset)以创建一个原始的工作目录来测试一个干净的构建
-X 只删除 Git 忽略的文件。这可能有助于从头重建一切,但保留手动创建的文件

2.12git clone

$ git clone --depth=1 https://github.com/bcit-ci/CodeIgniter.git #--depth=1 表示只下载最近一次的版本,使用浅复制可以大大减少下载的数据量
$ git fetch --unshallow#如果之后又想获取完整历史信息,可以这样fetch

2.13git branch

git branch -av #all & verbose[所有(远端和本地)&冗长的(Commit id前缀)]
git branch -d dev2 #删除分支
git branch -D dev2 #删除分支

2.14git log

git log -n2 #查看最近两次修改
git log Assets\AtlasSource\imagetext\skinlib\widget_cardgame\kapai_lan.png #查看某个文件的log

git-log
–full-history 包括merge的信息
git log --full-history .\gitTest\somethingInMaster.md

找包含Merge信息的提交
git log --all --grep=‘Merge’

12.14.1git show

git show都是基于commit hashID输出的。
1.查看最新的commit
git show
2.查看指定commit hashID的所有修改:
git show commitId
3.查看某次commit中具体某个文件的修改:
git show commitId fileName

2.3 Git 基础 - 查看提交历史
–stat 显示每次提交的文件修改统计信息。
git show --stat commitId >3d973889.txt

2.12git rebase

#改某个已commit的msg reword
git rebase -i d61e7b3 #从commit id开始变基交互式;r(reword),保存;改commit msg,保存.观察新的log,d61e7b3之后的commit id都不同的。具体如下:
#pick d61e7b3 addmaster2  ##这和条是没有的,因为是从d61e7b3开始变基
#pick c78b010 addmaster3  ##把这条的pick改成r,保存,关闭,然后改commit msg,保存,关闭,完成。即c78b010这条msg改好了。
#pick e457ca4 addmaster4

#多个连续commmit合并成一个commit
git rebase -i 8ed0783 #s(squash),压缩多个commit,把当前的commit向前合具体如下:
#pick d61e7b3 addmaster2  ##这和条是没有的,因为是从d61e7b3开始变基
#pick c78b010 addmaster3  ##这条不能改成s,因为它没有前一条
#pick e457ca4 addmaster4  ##把这条的pick改成s,保存,关闭,然后改commit msg,如addmaster3改成addmaster3  +4,保存,关闭,完成。即e457ca4 这条commit会合到前一条commit(c78b010)上。

git rebase -i 8ed0783 #s(squash),压缩多个commit,把当前的commit向前合,调整git-rebase-todo文件中commit id的顺序,使用git rebase --continue。具体类似上面的“多个连续commmit合并成一个commit”

2.12.1 merge vs rebase

Git merge和rebase分支合并命令的区别
有两本地分支,master和feature
merge:

#将分支切换到 master:
git checkout master
#将分支 feature 合并到当前分支(即 master 分支):
git merge feature

rebase
1、和 git merge 不同的是,你需要在 feature 分支上进行 git rebase master 的操作,意味着让当前分支 feature 相对于 分支 master 进行变基
2、我们遇到了冲突,进行对比的双方分别是 master 分支的最新内容和 feature 分支的第一次提交的内容,上图下方红框内容告诉我们,在我们解决了冲突之后,需要执行 git rebase --continue 来继续变基的操作。(用git add来标记解决冲突)
3、解决完冲突,会发现成了一条线。feature的base成了master的head,feature的commits在这个head之后。
4、回到master,将 feature 分支合并进来(用git merge feature),此时,master可以faster-forword了,所以master是一条线。
5、如果想把feature的几个提交合成一个提交,可以用git rebase -i 8ed0783 #s(squash)

#将分支切换到 feature:
git checkout feature
#将当前分支(即 feature 分支)变基成 master(变当前分支的基,把基成master的head):
git rebase master
# 如果有冲突,则:解决冲突,add ,rebase --continue
# git add 
# git rebase --continue
# 冲突解决完了,则完成
git merge,同一个冲突解决过了,再合并,会再冲突吗?

不会,因为合并的是“变更”,而不是“文件”。所谓的变更,就是加了一行,减了一行这种。而“文件”,即对比文件覆盖。因为这个变更已经合过了,就不会再有了。

2.13备份仓库

玩转Git三剑客_第1张图片
哑协议与智能协议
直观区别:哑协议传输进度不可⻅;智能协议传输可⻅。
传输速度:智能协议⽐哑协议传输速度快。

$ git clone D:\zjq\other-rep\learngit yaxieyi #哑协议
$ git clone file://D:\zjq\other-rep\learngit zhinengxieyi #file智能协议
$ git clone --bare file://D:\zjq\other-rep\learngit #--bare clone裸仓库,只有.git下的文件
$ git remote -v #查看远端
$ git remote add my_origin_name file://D:\zjq\other-rep\learngit #加远端
$ git push my_origin_name #push到指定远端,有默认值,origin, 这个默认值是通过“跟踪”完成的?

添加远端的实例

git remote add origin-out ssh://[email protected]:9200/family/bookvaccine.git

git会在本地仓库的.git文件夹下的config中添加一个remote的配置项。

更新远程分支列表

git remote update origin --prune

更新远程tag列表

git fetch origin #fetch 做的事情有点多

git tag -l | xargs git tag -d #删除所有本地分支
git fetch origin --prune #从远程拉取所有信息
git checkout 1.4 #切到指定tag

2.14git cherry pick

git cherry-pick <commit>

廖雪峰-解决冲突:
git add readme.txt 标记解决

git解决二进制文件冲突:
git checkout FILE --ours [ --theirs ]

Git操作 :从一个分支cherry-pick多个commit到其他分支

2.15git difftool

$ git difftool

2.16git prune

?
git gui
this repository currently has approximately loose 20000 objects

$ git prune # prune 修剪;删除;剪去;删除;减少 ?

将已有的项目添加到远端

Git–将已有的项目添加到github

git init
git add .
git commit -m ‘提交说明’
git remote add origin [email protected]:zhangjiequan/learn-unity.git #remote add origin 远程仓库地址
git push -u origin master

2.17git revert

git commitId1 
# 回滚commitId1 

git commitId3 commitId2 commitId1
# 依次回滚commitId3、commitId2、commitId1.所以,这里commitId3在commitId2之后提交的,123可以是分散的3个提交。即git revert NEWER_COMMIT OLDER_COMMIT

git commitId3^..commitId1
#  依次回滚commitId1、commitId2、commitId3,这里commitId3在commitId2之后提交的,123是连续的, 即git revert OLDER_COMMIT^..NEWER_COMMIT。如果是new^..old,则报错“error: empty commit set passed”,应该是没有这个集合,因为用new往后找,找不到old

git revert -n OLDER_COMMIT^..NEWER_COMMIT
# 合成一个提交

2.100git submodule

2.101 git hook

2.101.1 hook在mac上不生效的问题

hint: The ‘.git/hooks/pre-auto-gc’ hook was ignored because it’s not set as executable.
hint: You can disable this warning with git config advice.ignoredHook false.

设置成executable?
是的,默认是不可执行的。

chmod 777 <file>

参考:
Linux权限管理使用总结

2.102 git checkout vs git reset

撤销修改

场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改(即使用暂存区覆盖工作区)时,用命令git checkout – file。
场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD ,就回到了场景1,第二步按场景1操作。

# 把暂存区的内容放回工作区,包括修改、删除、增加文件。
git reset head
# 使用暂存区覆盖工作区
# 工作区改了文件、删了文件,都能用暂存区的去覆盖
# 不过,如果工作区增加了文件a/b.txt,则使用git checkout a,git checkout a/b.txt都无法删除工作区的文件
# 因为暂存区中无a/b.txt。即checkout不会对新增文件做删除
git checkout rsh-co.txt

3.Git 探秘

commit、tree、blob
HEAD、branch、Tag->commit
玩转Git三剑客_第2张图片
更多参见:高見龍 Git 連續劇

第三章:Git与GitHub简单同步

1.注册一个GitHub账号

2.配置公私钥

3.在GitHub上创建个人仓库

4.把本地仓库同步到GitHub

第四章:Git多人单分支集成协作时的常见场景

1.不同人修改了不同文件如何处理?

git clone [email protected]:pjgggg/pjgggg-client.git pjgggg-client_local_dic_name
git featch origin #简写为:git featch
git merge origin/release/hotfix-1#远端的hotfix合并到当前分支
#除了merge,也可以用rebase

2.不同人修改了同文件的不同区域如何处理?

#commit了,直接push会被拒绝,因为远端改了所以要:
git fetch # ahead 1,behind 1,即比远端“前了一个”,“又后了一个”
git merge orign/develop #将远端dev合到本地dev

或者直接git pull?
git pull等于git fetch + git merge?
git pull等于git fetch + git rebase?

用rebase的方式来pull

git pull --rebase
#或者详细写成以下,即加上origin远端名,develop分支名 
git pull --rebase origin develop

3.不同人修改了同文件的同一区域如何处理?

4.同时变更了文件名和文件内容如何处理?

5.把同一文件改成了不同的文件名如何处理?

第五章:Git集成使用禁忌 (2讲)

1.禁止向集成分支执行push -f操作

push -f 强制push,直接覆盖远端。
github gitlab有相关机制禁止push -f。

2.禁止向集成分支执行变更历史的操作

向集成分支执行变更历史的操作,如rebase一下,改一下历史的commit msg。
如果执行了,其它的开发者会懵逼。

其它

1批量clone

使用Python 3通过gitlab的web api拿到json后逐一clone

git-game

git-game
git-game-v2
参考答案:
Git Game: Copying and Pasting From Documentation
Git Game v2: Copying and Pasting From Stack Overflow
来自华工计院16级的小师弟,写得比较详细,有趣(从标题能看出一二,哈哈)

learn git branching

learn git branching

你可能感兴趣的:(Git)