“我报名参加金石计划1期应战——分割10万奖池,这是我的第2篇文章,点击检查活动概况”

前语

记载运用 Git 时一些或许不常用,可是值得了解的功用和指令。

patch 功用

patch 这个词有许多意思,在 Git 当中或许说在计算机中常常译为 补丁

补丁是指衣服、被褥上为遮掩破洞而钉补上的小布块。现在也指对于大型软件系统(如微软操作系统)在运用过程中暴露的问题(一般由黑客或病毒设计者发现)而发布的解决问题的小程序。就像衣服烂了就要打补丁一样,人编写程序不或许十全十美的,所以软件也免不了会呈现BUG,而补丁是专门修正这些BUG做的由于原来发布的软件存在缺陷,发现之后另外编制一个小程序使其完善,这种小程序俗称补丁

gif diff 或许天天在用,其实运用 git diff 的成果再延伸一下,就能够有别的用途了。

个人关于对这个功用的了解,还有一段小插曲。

某日由于疫情突发居家工作,可是笔记本刚好没有带回家,遂用家里的电脑开端工作。打开电脑忽然想起前一日写的代码没有提交(主要是功用没写完,想着写完了一同提交)。让公司搭档帮助提交后又发现有冲突,解起来比较棘手。随一想自己需求的仅仅个人在本地的改动,即本地的 diff 。只需经过任何方法能获取到本地一切的改变即可,暂时和代码仓库里其他的提交没有关系。gif diff 不就能够输出代码改变吗?那么如何将这些改变快速的转移到自己家里的电脑上,而且直接运用呢?在探索的过程中就发现了 git patch。

那么 patch 功用到底怎么用呢?下面用一个简略的 demo 来阐明一下。简略起见,咱们用一个文本文件实例一下(就不必代码了,意思都一样的)

现有 notes.txt 文件,现已进行了一次 commit ,咱们对其进行一些修正,具体细节如下。

notes.txt init commit notes.txt 修正后
几个值得了解的 Git 操作
几个值得了解的 Git 操作

此时咱们运用 git diff > diff.patch 指令能够看到 diff.patch 生成了如下内容。

diff --git a/notes.txt b/notes.txt
index c5aab4b..7d65678 100644
--- a/notes.txt
+++ b/notes.txt
@@ -1,5 +1,5 @@
 book
-music
-art
 moive
 sport
+food
+sleep

这部分内容很很熟系了,平时用 git diff 指令检查文件改变时都见过,git 以行为单位,记载文件的改变,- + 都能够理解为某一行代码发生改变,或许是删去了,也或许是彻底新增,或许是这一行做了修正(修正也能够理解为删了一行,又新增了一行)。

有了 diff.patch 文件,咱们就能够脱离长途仓库完成两台物理机代码改变同步了,分布式 yyds 。

咱们在另一个同源的仓库,就能够把这个 patch 打上去了。

git apply diff.patch

~/Desktop/test/1111/demo  ‹master*› $ cat notes.txt
book
music
art
moive
sport
~/Desktop/test/1111/demo  ‹master*› $ git apply diff.patch
~/Desktop/test/1111/demo  ‹master*› $ cat notes.txt
book
moive
sport
food
sleep
~/Desktop/test/1111/demo  ‹master*› 

能够看到 patch 现已收效了。

这样,在公司的搭档只用生成一个 patch, 把这个 patch 文件发给我,这样就简略多了。而我呢就能够接着之前的成果持续搬砖了。

patch 功用小结

  1. 上面尽管是用单个文件做比方,但其实多个文件也是能够的,都能够输出到单个 *.patch 文件中。乃至能够根据自身的需求,某几个文件的 diff 生成一个 patch,然后将这个 patch 打到合适的当地。
  2. patch 本质上是代码的改变记载;因而,除了根据 git work-space 的改变生成 patch ,咱们也能够根据前史 commit 生成 patch。
  3. git diff 是根据 git track 过的文件生成 diff,因而初次新增的文件,最起码要 add 过之后才会有 diff 发生。当然,git diff 自身就很灵活了,能够根据当时 work-space 的改变或许 git HEAD~N 前史提交输出 diff ,更多用法能够检查文末的参阅文档。
  4. patch 功用只能用于文本文件,无法对资源类文件(比方图片、音视频资源)收效。尽管 patch 能够记载资源文件的改变,可是 apply 是会失败的。想想也不太或许嘛,用一个简略的 patch 文件记载两个视频文件的差异,技能上有或许,可是形似没有实际意义。
  5. git apply patch 和常用的 git cherry-pick 非常类似。可是侧重点不同,patch 更多时分是和第三方合作开发的场景。比方 Android 底层一些硬件驱动的改变、bug 的修正。一般都是由专门的厂商将修正以 patch 的方法给到运用方,运用方将这个 patch 打上就能够了。能够看到做了哪些改变,但也仅此而已。 cherry-pick 的运用场景就比较灵活了,任何需求某个特定 commit 的场景,都能够用。有时分被 git merge 搞得代码一片紊乱的时分,cherry-pick 不失为解决问题的一种好办法。
  6. git 有专门的指令能够生成更加丰厚的 patch ,能够检查文末的参阅文档。

这儿仅仅刚好运用 git patch 完成了两台物理机的代码更变同步。实际上关于本地代码不经过长途仓库在两台物理机同步的解决方案太多了,这儿仅仅趁便了解一下 patch 的运用。

几个值得了解的 Git 操作

shortlog

这个指令就比较好玩了,能够参阅 git 仓库一些有意思的信息。

这儿以大名鼎鼎的 okhttp 代码库做演示。

  • 检查 git 仓库有哪些人做过 commit

在 okhttp 仓库下履行以下指令,便能够看到输出

git shortlog -sn
  2082  Jesse Wilson
  773  Jake Wharton
  594  jwilson
  586  Yuri Schimke
  231  Adrian Cole
   78  renovate[bot]
   73  Amir Livneh
   56  Neil Fuller
   55  Dave Roberge
   54  Goooler
   30  Marcelo Cortes
   25  limpbizkit@gmail.com
   19  Eric Cochran
   18  Shaishav Gandhi
   16  Benoit Quenaudon
   15  Masaru Nomura
   14  Benot Quenaudon
   12  Tobias Thierer
   11  jessewilson@google.com
   11  Patrick Forhan
   11  Egor Andreevich
   10  Narayan Kamath
   10  lingming.yb
    9  TangHuaiZhe
    9  monkey-mas
    9  edenman
更多内容,点击检查
     7  Zac Sweers
     6  Artem Zinnatullin
     6  Christian Becker
     6  Tang HuaiZhe
     5  Steve Lhomme
     5  Michael Benedict
     5  ericaschulz
     5  Kristopher Wuollett
     4  Anton Rutkevich
     4  John Carlson
     4  cketti
     4  Jeremy Tecson
     4  Egor Andreevici
     3  Isaac Green
     3  Erik Ghonyan
     3  Rob Bygrave
     3  RayFromSquare
     3  Andre_601
     3  Andrew (Paradi) Alexander
     3  Roberto Tyley
     3  swankjesse
     3  Thz
     3  Alex Klyubin
     2  Bjrn Kautler
     2  Alok Menghrajani
     2  Andreas Ahlenstorf
     2  Andrew Shu
     2  Anton Rieder
     2  Carter Kozak
     2  Cedric Luthi
     2  David Phillips
     2  David Robertson
     2  Eric Edens
     2  Felipe Lima
     2  Francisco Montiel
     2  Galder Zamarreno
     2  Grgory Joseph
     2  Jared Burrows
     2  Jeff Gilfelt
     2  Jochen Schalanda
     2  Jung KyungHo
     2  Kartikaya Gupta (kats)
     2  Lorenzo Colitti
     2  Megatron King
     2  Michael Parker
     2  Niklas Baudy
     2  Noriyoshi Fukuzaki
     2  Rainer Burgstaller
     2  Ras Kasa Williams
     2  Richard Thai
     2  Roman Tsirulnikov
     2  Said Tahsin Dane
     2  SatoShun
     2  Simon Marquis
     2  Stefan M
     2  Venil Noronha
     2  Warren Smith
     2  Yuanjing Zhang
     2  boxme
     2  shellhub
     1  Frieder Bluemle
     1  Galder Zamarreo
     1  Gatan Muller
     1  Georgi Staykov
     1  Giovanni Longatto Nazario Marques
     1  Gonalo Silva
     1  Colton Loewen
     1  longbai
     1  Guillaume Legrand
     1  Guillermo Rodrguez
     1  HearSilent
     1  Herman Liang
     1  Hugo Gresse
     1  Ignasi Barrera
     1  Igor Fedorenko
     1  Clment Dessoude
     1  Jairus Mendoza
     1  Christopher Orr
     1  James Tucker
     1  marcinbak
     1  Jason Holmes
     1  Jasper Vandemalle
     1  Jay Estrella
     1  Jay Newstrom
     1  Jaye Pitzeruse
     1  Jeff Bornemann
     1  mattlogan
     1  Jemar Jones
     1  Christopher Kocel
     1  Christoph Sitter
     1  Jim Hurne
     1  mic-
     1  Johan von Forstner
     1  Christian Brunotte
     1  John Rodriguez
     1  Jon Ander Pealba
     1  Jon Watson
     1  Jonathan Halterman
     1  Jonathan Leitschuh
     1  Jonathan Steele
     1  Jonh Wendell
     1  Jordan Stewart
     1  Joshua Shanks
     1  mike castleman
     1  Juti Noppornpitak
     1  Kai Zhu
     1  Adam Howard
     1  Kasra Bigdeli
     1  Kazuhiro Sera
     1  Kenny Root
     1  Kevin Robatel
     1  Kiran + Kenji
     1  Kirill Boyarshinov
     1  Krishna Chaitanya M
     1  Chris Cunniff
     1  Lavong Soysavanh
     1  Liam Newman
     1  Lin Wang
     1  mruddy
     1  Lucas Albuquerque
     1  Lukas Aichbauer
     1  Maciej Grski
     1  Manish Sharma
     1  Manuel Jimnez Torres
     1  Marc Reichelt
     1  Chad Brubaker
     1  Marcin Zajczkowski
     1  Mark Hobson
     1  Markta Lisov
     1  Marvin Ramin
     1  Brian Odisho
     1  Matt Sheppard
     1  Matthew Zavislak
     1  Maxim Shafirov
     1  nithasha-samad
     1  Michael Arenzon
     1  Michael Basil
     1  Brennan Taylor
     1  Michael Evans
     1  nmittler
     1  Miguel Lavigne
     1  (no author)
     1  Nash Lincoln
     1  Baldur Gudbjornsson
     1  Nguyn Triết Khang
     1  Nicklas Ansman Giertz
     1  Nicola Corti
     1  Nicols Lichtmaier
     1  nxtstep
     1  olg
     1  Norman Maurer
     1  Oliver
     1  Ollie Snowden
     1  PY
     1  Austyn Mahoney
     1  Patrick Strawderman
     1  Paul Fulham
     1  Paul Knudsen
     1  Paul Woitaschek
     1  Pavel Chuchuva
     1  Phil Glass
     1  Philip Jagielski
     1  Prashant Jois
     1  Quinn Neumiiller
     1  panmingwei
     1  Ralph Bergmann
     1  raskasa
     1  Atticus White
     1  Reinhard Naegele
     1  Reinhard Ngele
     1  rattanshiv12
     1  Ricki Hirner
     1  Rob
     1  Artem Gavrilov
     1  Arlo Breault
     1  rbates
     1  Russell
     1  Ryan O'Meara
     1  Aakash Goenka
     1  Saket Narayan
     1  Santiago Castro
     1  rupertbates
     1  Sean C. Sullivan
     1  Sebastian Krten
     1  Sebastian Schuberth
     1  Sergey Galkin
     1  Serj Lotutovici
     1  Andy Dennie
     1  shaunkawano
     1  Simon Wimmesberger
     1  Skeiro
     1  Stanislav Gromov
     1  靳阳
     1  Stephen Barlow
     1  Andrew Gaul
     1  Stuart Neivandt
     1  Amir Jalal
     1  Amin Cheloh
     1  TangHuaizhe
     1  Tao.Zang
     1  Taylor H. Perkins
     1  Teresa Krause
     1  Thomas Keller
     1  Thomas Wirth
     1  Alexey Zakharov
     1  Tobias T
     1  Alex Wegener
     1  Tolriq
     1  Tom Reznik
     1  Tomasz Rozbicki
     1  Tony Robalik
     1  Tyler Barber
     1  Usmann Khan
     1  AJ
     1  Volodymyr Buberenko
     1  Voytovich, Mike
     1  utsavoza
     1  Wesley Tarle
     1  When Sunset
     1  WhiskeyBravo
     1  Yahia Allam
     1  Yang Chen
     1  Ye Lin Aung
     1  vlad doster
     1  Alex Szlavik
     1  Alex
     1  aahlenst
     1  abeggs
     1  ahulyk
     1  anderius@gmail.com
     1  austynmahoney
     1  based2
     1  bdc@google.com
     1  南宫雪珊
     1  chhsiao90
     1  circlespainter
     1  Ahmed El-Helw
     1  congwu.wang
     1  dc
     1  Adrian Pascu
     1  edenman@gmail.com
     1  Adrian Cole and Josh Humphries and Scott Blum
     1  gkimbwala
     1  iamdanfox
     1  ittzik
     1  Adrian Cole and Jesse Wilson
     1  jjshanks
     1  Danstahrg
     1  Daniel Tashjian
     1  Adam Taft
     1  lburgazzoli
     1  Dimitris+Jake
     1  Dino Dai Zovi
     1  Dino Kova
     1  Dmitry Timofeev
     1  Dmitry Zolotukhin
     1  DracoBlue
     1  Dustin Kut Moy Cheung
     1  Edd Melndez Gonzales
     1  Daniel Cohen Gindi
     1  Dan Snduleac
     1  Eitan Adler
     1  Elvis de Freitas
     1  Emilian Bold
     1  Emre
     1  Craig Andrews
     1  Eric Denman
     1  len
     1  Eric Gribkoff
     1  Eric Kuck
     1  Craig
     1  Everett Toews
     1  Faucogney Anthony
     1  Adam Stroud
     1  Florent Ramire
     1  lingming
     1  Adam Speakman

有没有找到自己的姓名或许是认识的大佬 ,罒罒 。只需提过 PR 而且合入也算是 commitor ,所以能够看到许多 commit 次数为 1 的人。

经过 git shortlog -sn 能够显现当时仓库的一切提交者,而且会按提交 commit 的数量进行降序摆放。(当然,这个 commit 数量并不能阐明什么,可是能够简略了解一下这个仓库有哪些人做过奉献)。

运用 git shortlog -sne 还能够显现邮箱。 git shortlog 本质上是对 git log 输出的内容进行格式化处理。关于 shortlog 更多的用法能够经过 –help 指令检查。

如果你真的看过 git shortlog --help 的帮助文档,其实还能够发现其他一些有意思的指令行。

  • 获取最新一次 commit 的 commit-id
git rev-parse --short HEAD  // 回来 commit-id 前 7 位
// or 
 git rev-parse HEAD // 回来完整的 commit-id

ps:这儿其实有个有意思的问题,为什么这个 hash 值前 7 位就能够代替这个 hash 值?

  • 获取最新一次 commit 的 branch
git rev-parse --abbrev-ref HEAD
  • 获取最新一次 commit 的 author_name
git log -1 --pretty=format:'%an'
  • 获取最新一次 commit 的 author_email
git log -1 --pretty=format:'%ae'

当然了,这些信息也能够经过其他方法获取,乃至现在各类 IDE 对 git commit history 的支持都非常完善了,能够直接检查了。

git blame

经过 git blame 能够快速检查某个文件的提交前史。

git blame filename

会按行显现提交记载

增加 -L 参数能够指定行。

git blame -L startline,endline filename

特定行数的提交记载

当然,这个功用 Github 自身便是支持的。

git tag

在平日运用 git 的时分,大家更习惯的是运用分支 branch 。在 git 中,如果说 branch 是随着 commit 越来越多不断延伸的一条河流的话,那么每创立一个 tag 便是在这条河上面制作一座桥。

从任意 git commit 结点创立分支 branch 之后,能够就此分支做 commit , merge 等操作,是动态的;从这个层面动身,git tag 便是静态的。

因而,git tag 在日常开发中运用较少。乃至在某些开发团队,git tag 的创立由专人负责(一般是版别迭代负责人)。 git tag 一般是在一些特殊的、里程碑式的提交结点创立。比方在 App 封版的提交,SDK 特定版别的提交。

git tag 的运用也比较简略。

  • 创立 tag
git tag tag_name
  • 检查一切 tag
git tag

咱们能够看一下 okhttp 的 tag.

git tag --sort=-creatordate
parent-5.0.0-alpha.10
parent-5.0.0-alpha.9
parent-4.10.0
parent-5.0.0-alpha.8
parent-5.0.0-alpha.7
parent-5.0.0-alpha.6
parent-5.0.0-alpha.5
parent-5.0.0-alpha.4
parent-5.0.0-alpha.3
parent-4.9.3
parent-4.9.2
  • 删去 tag
git tag -d tag_name

需求留意的是,创立 tag 之后,并不会在 work-space 有记载。由于 tag 能够理解为是某个 commit 的一个影子。其本质上并没有生成新的东西。tag 也不会随 commit 的 push 主动带到长途仓库中,tag 需求手动进行 push

git push <remote> <tag_name>:推送某个标报到长途仓库。
git push <remote> --tags:推送一切标报到长途仓库。

关于 git tag 的更多运用阐明,能够检查文末参阅文档。

git reflog

  • 康复现已被 reset 或删去的 commit 记载
git reflog

git reflog 许多时分都是 git 误操作的后悔药。

  • 不小心删去的 commit 记载,
  • merge 代码时误操作干掉的 commit ,
  • git reset –hard 之后又想找回来的提交记载,
  • 被删去的分支找不到 commit-id 了,无法康复时

统统能够经过 git reflog 找回来。

git reflog 显现的内容本质上是 git commit 的在本地的一切操作记载。因而,并不能百分之百保证一切提交记载能够被康复,因而 git 有定期进行 commit 主动清理的策略

因而,不能过度依赖 git reflog, 对仓库进行随意的操作。

希望你的程序员生计不必用到这个指令来救火。

to be continued

参阅文档

  1. blog.csdn.net/csfchh/arti…
  2. blog.csdn.net/u012701023/…
  3. Git 官方文档
  4. blog.csdn.net/qq_21746331…