【工具学习】git使用 - hippowc/hippowc.github.io GitHub Wiki

git 最佳实践

git config 配置

  • git config -l 列出所有配置
  • git config --global user.name "" 全局配置用户名
  • git config --global user.email "" 全局配置邮箱

git init 初始化

  • git init 本地生成.git文件

git add 添加本地文件

  • git add ./ 添加到暂存区

git commit 提交

  • git commit -m 提交到本地仓库

git remote 远程仓库操作

  • git remote -v 查看远程仓库详细信息
  • git remote add 添加远程仓库信息

git branch 本地分支操作

  • git branch 新建分支
  • git branch -d 删除本地分支

git push 推送到远程

  • git push -d <远程仓库> <远程分支名> :删除远程分支
  • git push -u <远程仓库> <远程分支名> :根据本地分支新建远程分支,并关联

git log 查看git提交日志

  • git log --oneline 简化到一行显示
  • git log --pretty=oneline/raw 对齐显示
  • git log --grep <关键字> 按照commit信息搜索

git checkout 检出到工作区

  • git checkout 切换分支, ps:切换分支是如果本地修改为提交,会带到下个分支,但是提交之后,就不会保留修改到下个分支了
  • git checkout <commitID/tag> 将某次提交检出到当前工作区,不填commitId默认将暂存区的检出
  • git checkout -- 只检出某个文件
  • git checkout --track <远程仓库>/<远程分支名> :远程有分支本地没有

git reset 重设分支

  • git revert 重设分支
  • git revert -- 只重设某个

checkout、revert与reset

三个命令都可以退回到之前的某个提交,但有所不同,先说commit级别的修改,

  • ps1: git不仅可以到之前的commit,也可以到后面的commit
  • ps2: 删除的也可以恢复

checkout

  • checkout是将HEAD指针移动到特定的commit,但是并没有和分支一起移动,这个时候如果没在任何分支上,HEAD是独立的状态,这个时候的commit会找不到
  • 适用场景:只是查看历史,而不要修改
  • 注意:因为checkout会修改本地文件,所以要先stage或commit本地内容

revert

  • 只能是commit级别
  • revert会创建一个commit — 使用场景:修改公共分支
  • 注意:revert是一种安全的方式做退回,因为它没有修改commit历史

reset

  • reset 将HEAD指针和branch一块移动到特定的commit,可以继续修改和提交
  • 适用场景:修改个人分支
  • --soft 保留工作区、暂存区;--mixed 保留工作区(默认);--hard 不保留

checkout和reset还可以用在文件级别的退回

reset

  • undo暂存区,工作区保留
  • --soft/mixed/hard都不再起作用

checkout

  • undo暂存区,undo工作区,但是对于新增文件,无法undo
  • 分支不变
  • 似乎对于新增文件无法删除

git tag (可以直接用于脚本工程发布的版本管理)

  • git tag tagName 在当前commit增加tag,tag是一个到某个commit的指针,用于保存重要提交版本,譬如发布版本
  • git tag -d tagName 删除tag
  • git tag -a tagName -m message 附注标签,会携带多一些信息,譬如打标者信息,日期等,可校验
  • git push origin tagName 默认push不携带tag信息,需要显示推送
  • git push origin :tagName 删除远程tag
  • git push --tags 推送所有tag
  • git checkout tagName 检出某个tag
  • git checkout -b branchName tagName 因为checkout不会携带分支一块移动,如果打算在tag上进行修改提交,需要同时新建分支

git merge

  • git merge 合并分支
  • --strategy-option=theirs/ours 合并,如果出现冲突统一使用theirs或者ours

git diff 比较命令

  • git diff // 比较工作区和暂存区
  • git diff HEAD // 比较工作区和本地仓库
  • git diff --cached // 比较暂存区和本地仓库
  • git diff commitAhash commitBhash -- filename // 比较两次提交中某个文件的不同,含义是commitBhash的filename文件比commitAhash多/少了那些东西
  • git diff commitAhash HEAD -- filename // 比较当前分支与commitAhash相比改变了那些文件
  • git diff --name-only // 比较哪些文件修改了,不看细节

git stash 暂存命令

  • git stash :将未提交到本地的代码暂存起来,包括add和未add的,保证工作区和上一次commit一致
  • git stash pop: 从Git栈中读取最近一次保存的内容,恢复工作区的相关内容。由于可能存在多个Stash的内容,所以用栈来管理,pop会从最近的一个stash中读取内容并恢复。
  • git stash list: 显示Git栈内的所有备份,可以利用这个列表来决定从那个地方恢复。
  • git stash clear: 清空Git栈。此时使用gitg等图形化工具会发现,原来stash的哪些节点都消失了。

git基础

  • 三个空间
    • 工作区
    • 暂存区
    • 提交历史
  • 两个指针,指针都会指向commit节点(commitID)
    • HEAD指针
    • 分支指针
  • HEAD 代表当前指针,可以方便的代表当前commit

HEAD是什么?

git中每提交一次,会产生一个commitId,是一个hash值

HEAD代表的是当前版本,也就是最新一次提交的commitId,上一个版本是HEAD^,上上个版本是HEAD^^,上100个版本HEAD~

其实HEAD只是一个指针,指向当前版本。在使用reset命令进行版本回退或者前进(可以前进,只要有commitId),只是HEAD指针变化同时更新工作区。

git对象

git是一套内容寻址文件系统。意思是:git会简单存储键值对。可以插入任何内容(变更文件的快照),返回一个键值,然后通过该键值可以取出内容。

git的底层命令hash-object,这个命令可以将任何数据保存到.git/objects目录下,并返回键值。

如:$ echo 'test content' | git hash-object -w --stdin

可以通过cat-file命令取回该值

如:git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4

git commit就相当于:

$ echo 'version 1' > test.txt

$ git hash-object -w test.txt

将最新的文件新增到文件库中。

git reset就相当于:

$ git cat-file -p 83baae61804e65cc73a7201a7252750c76066a30 > test.txt

将文件取出并覆盖到源文件

--blob对象,存储变更文件快照

--tree对象。tree中保存了仓库下的目录情况

git所有对象以tree或blob对象存储,tree相当于目录,blob相当于文件内容。

git的write-tree命令可以根据文件的index创建tree对象,当将文件放入暂存区中时,会自动创建index文件。

--commit对象,记录顶层树对象,作者信息,时间戳,注释信息。提交之后commit中保存的是顶级的tree目录的信息。

.gitignore

在项目目录下(和.git同级)建立.gitignore文件,用以排除不需要的文件

常用匹配示例:

  • bin/: 忽略当前路径下的bin文件夹,该文件夹下的所有内容都会被忽略,不忽略 bin 文件
  • bin: 忽略当前路径下的bin文件夹和bin文件
  • /bin: 忽略根目录下的bin文件
  • /*.c: 忽略 cat.c,不忽略 build/cat.c
  • debug/*.obj: 忽略 debug/io.obj,不忽略 debug/common/io.obj 和 tools/debug/io.obj
  • **/foo: 忽略/foo, a/foo, a/b/foo等
  • a/**/b: 忽略a/b, a/x/b, a/x/y/b等
  • !/bin/run.sh: 不忽略 bin 目录下的 run.sh 文件
  • *.log: 忽略所有 .log 文件
  • config.php: 忽略当前路径的 config.php 文件

ssh-keygen的使用

ssh-keygen只是用来生成公钥和私钥的工具。默认会生成到.ssh文件目录下。每次ssh访问后会将访问时使用的公钥添加到known_hosts这个文件下,以便后续使用。

如果秘钥对发生过变更,可以使用ssh-keygen -R hostname,将这个记录清除掉。

关于github使用免秘钥认证:

1、首先在git config中使用ssh的方式而不是https的方式连接。

2、使用ssh-keygen -t rsa 生成秘钥

3、将私钥粘贴到相应github仓库中即可。

4、github可以再账户层面增加sshkey,也可以在仓库层面增加deploykey

5、以账户的sshkey为例子

6、github上保存的是public key

7、你本地使用的是private key

8、提交内容到远程分支的时候,ssh会使用私钥加密某些信息(还不知道是什么),然后github使用公钥验证,成功即可。完后ssh会将记录这个公钥和域名的对应信息到known_hosts,known_hosts中是根据域名区分的,一个域名只能认证一个用户。

9、这个public key就是你抽象的个人信息,虽然没有邮箱什么的,你的同一个public key可以粘在不同的github账户中,都可以使用,但是github只允许你对应一个,在保存时会校验publicKey的唯一性。

⚠️ **GitHub.com Fallback** ⚠️