提前使用Geeta还是六个月前如何退休?


我不知道您使用的是哪种编程语言,但是我确定您在开发过程中会使用Geet。 有越来越多的工具来支持开发,但是即使是最小的测试项目,我也总是从git init命令开始。 在工作日中,我平均会再输入80个团队,以引用此版本控制系统。


当我开始重新学习十指印刷方法时,我非常紧张。 最后,这是改善您的个人工作流程的最佳决定。 接下来最重要的优化是Geeta的高级开发。


关于Gita的许多文章已经在Habr上写过,但是它们并没有超出官方文档的范围,并且作者建议使用自制的拐杖简化工作。 我相信有必要研究Geet的具体任务示例,并提高使用标准化手段处理它的效率。


谁将从本文中受益?


您已经掌握了绅士的《吉塔》系列,并且准备好继续前进了吗? 有两种方法:


  1. 主缩略命令-别名。 它们几乎总是助记符且易于记忆。 忘记原始命令是有问题的,我在需要时轻松键入它们。 另外,我不会在编写代码时检查Gita中的内容而感到困惑。
  2. 了解有关团队的其他标志以及它们之间的集成。 我了解有人讨厌切割。 对于您来说,文章中也有有趣的内容- 如何提高命令输出的实用性和便利性,以及如何解决最琐碎但在实践中经常遇到的问题

今天花几个小时参加本文所述的实验,并通过近似计算节省六个月的工作寿命。


欢迎来到猫!


准备工作


在开发人员中, Bash替代产品的标准是Zsh ,它是支持微调的高级软件外壳。 在Zsh用户中,标准是使用Oh My Zsh ,这是Oh My Zsh一组预定义设置。 因此,安装了该工具包后,我们将立即摆脱社区多年来为我们收集和开发的一系列黑客。


值得注意的是, Zsh适用于LinuxMacWindows


安装ZshOh My Zsh


根据说明使用一个命令安装ZshOh My Zsh


 # macOS brew install zsh zsh-completions && sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)" # Ubuntu, Debian, ... apt install zsh && sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)" 

由于任务是优化与Geet的交互,因此我们将向Zsh添加几个插件。 打开~/.zshrc ,并将plugins添加到列表中:


 plugins=(git gitfast) 

总计:


  • git一组别名和辅助功能;
  • gitfast增强了Gita的自动完成功能。

tig设定


最后一点是tig控制台实用程序的安装:


 # macOS brew install tig # Ubuntu, Debian, ... # https://jonas.imtqy.com/tig/INSTALL.html 

我们将进一步讨论。


实践中的Git


与Geeta打交道最好通过解决特定的问题来完成。 接下来,我们考虑日常实践中的任务以及可方便解决的方案。 为此,请考虑使用带有文本文件的特定存储库。


黄色方框表示本节中解决问题的主要别名。 仅学习它,并将其他所有东西留给一般开发。

检查工作目录的状态


让我们从最基本的事情开始。 我们做了一些工作,现在让我们看看工作目录中发生了什么:


 $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: e.md Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: b.md Untracked files: (use "git add <file>..." to include in what will be committed) d.md 

详细描述了所有文件的当前状态,并提供了其他操作说明。 刚开始使用Geeta时,它非常有用,但是日常工作中有很多多余的东西。 让我们通过其他按键降低噪声级别:


 $ git status -sb ## master M b.md A e.md ?? d.md 

是的,我们在master分支中,更改了b.mdM-odified b.md )文件并创建了两个文件,将第一个添加到Geeta索引( A-dded ),然后将第二个添加到索引之外( ?? )。 简短明了。


仍然需要通过别名g it s tatus with b ranch”来优化此命令的无尽输入:


显示缩短的工作目录状态

 $ gsb # git status -sb 


创建一个提交


我们继续。


当然,您可以进行提交。 但是,让我们尝试优化此简单任务的解决方案。 使用别名g it dd dd ll”将所有更改添加到索引:


 $ gaa # git add --all 

我们使用别名g it diff ched”来检查索引是否恰好满足了我们的需要:


 $ gdca # git diff --cached diff --git a/b.md b/b.md index 698d533..cf20072 100644 --- a/b.md +++ b/b.md @@ -1,3 +1,3 @@ # Beta -Next step. +Next step really hard. diff --git a/d.md b/d.md new file mode 100644 index 0000000..9e3752e --- /dev/null +++ b/d.md @@ -0,0 +1,3 @@ +# Delta + +Body of article. 

嗯,解决单个任务的更改应该落入一次提交。 在这里,两个文件的更改都不会以任何方式连接。 让我们从别名为g it r set n ndo”的索引中排除d.md文件:


 $ gru d.md # git reset -- d.md 

并创建一个别名为g it c ommit”的提交:


 $ gc # git commit 

我们写出提交的名称并保存。 然后,使用别名g it commit m e s sa g e”,使用更熟悉的命令为d.md文件创建另一个提交:


 $ gaa #    $ gcmsg "Add new file" # git commit -m "Add new file" 

我们可以...


...使用一个命令从索引提交修改的文件:


 $ gcam "Add changes" # git commit -a -m "Add changes" 

...查看按单词而不是行的更改(在处理文本时非常有用):


 $ gdw # git diff --word-diff 

...分部分添加文件(当您只需要将文件更改的一部分添加到提交中时非常有用):


 $ gapa # git add --patch 

...仅将已经在Geeta监督下的文件添加到索引中:


 $ gau # git add --update 

总计:


添加到索引/创建提交

 $ ga # git add $ gc # git commit 


修正提交


上次提交的名称不能解释我们所做的更改。 让我们重新制定:


 $ gc! # git commit -v --amend 

在打开的文本编辑器中,我们将其更清楚地称为: "Add Delta article" 。 我确信您永远不会使用-v开关,尽管在编辑提交说明时,它会显示所做的所有更改,这有助于更好地导航。


我们可以...


...使文件更改为提交,但不要触摸描述:


 $ gcn! # git commit -v --no-edit --amend 

...使所有文件更改立即提交,而无需先添加到索引:


 $ gca! # git commit -v -a --amend 

...结合前两个命令:


 $ gcan! # git commit -v -a --no-edit --amend 

好了,请再次注意,我们只输入了三个字符,而不是键入完整的常规git commit -v --amend


更改最后一次提交

 $ gc! # git commit -v --amend 


新功能入门


从当前别名g it c heckout b ranch”创建一个新分支:


 $ gcb erlang # git checkout --branch erlang 

尽管没有,但最好写一篇有关Elixir别名“用钥匙移动它”更现代语言的文章(在Gita中重新命名是通过move ):


 $ gb -m elixir # git branch -m elixir 

使用别名gbmv是合乎逻辑的,但是不幸的是,它尚未被发明。 一个好的选择。


我们已经知道:对存储库进行更改并创建一个提交:


 $ echo "#  —     ." > e.md $ gaa && gcmsg "Add article about Elixir" 

并记住:


创建一个新分支

 $ gcb # git checkout --branch 


合并变更


现在,我们将有关Elixir的新文章添加到master 。 首先,切换到别名为g it c heckout m aster”的主分支:


 $ gcm # git checkout master 

不,真的。 三种易于记忆的字符中最常用的命令之一。 现在,别名更改的名称为“ gerge”


 $ gm elixir # git merge elixir 

糟糕,但是已经有人设法对master进行更改。 而不是我们的项目采用了优美的线性历史,我创造了 讨厌的 合并提交。


合并分支

 $ gm # git merge 


删除最后一次提交


不用担心! 您只需要删除最后的提交,然后尝试再次合并更改g r reset hh ard”


删除上一次提交

 $ grhh HEAD~ # git reset --hard HEAD~ 


我们解决冲突


用于准备线性更改历史记录的标准checkout – rebase – merge序列由以下别名序列执行:


 gco elixir # git checkout elixir grbm # git rebase master gcm # git checkout master gm elixir # git merge elixir 

所有这些字母都经常被使用,以至于它们已经从手指上飞走了,在执行此类操作时,无需考虑要键入哪一组字母。 并且不要忘记,在Zsh您可以使用Tab键来补充分支的名称。


变基

 $ grb # git rebase 


将更改提交到服务器


首先,我们添加origin别名g it r emote dd”的 origin


 $ gra origin git@github.com/... # git remote add origin git@github.com/... 

然后,我们将更改直接发送到存储库的当前分支( “ gg” -命令开头加倍的g表示当前分支中操作的执行):


 $ ggpush # git push origin git_current_branch 

您也可以...


...将更改与upstream安装的g 向上推送”别名发送到服务器:


 $ gpsup # git push --set-upstream origin $(git_current_branch) 

将更改提交到服务器

 $ gp # git push 


我们收到来自服务器的更改


工作如火如荼。 我们设法将新文章f.md添加到master ,而我们的同事更改了文章a.md并将此更改发送到服务器。 这种情况也可以很简单地解决:


 $ gup # git pull --rebase 

然后,您可以安全地将更改发送到服务器。 冲突解决了。


从服务器获取更改

 $ gl # git pull 


删除合并的分支


因此,我们成功地将几个分支合并到master ,包括上一个示例中的elixir分支。 我们不再需要它们了。 您可以删除别名g it ranch delete a nother”


 $ gbda # git branch --no-color --merged | command grep -vE "^(\*|\s*(master|develop|dev)\s*$)" | command xargs -n 1 git branch -d 

非常美丽而狡猾的团队。 通常我会忘记清除失去相关性的分支,而这支优雅的团队是真正的救赎。 如果您不想使用别名,只需将命令的完整版本复制到笔记中,然后根据需要执行即可。


创建一个临时提交


h.md有关Haskell的新文章正在紧锣密鼓地进行。 写了一半,您需要得到同事的反馈。 无需三思 ,我们输入别名g it w ork i n p rogress”


 $ gwip # git add -A; git rm $(git ls-files --deleted) 2> /dev/null; git commit --no-verify -m "--wip-- [skip ci]" 

然后创建一个名称为Work in Progress的提交,跳过CI并删除“多余”文件。 我们将分支发送到服务器,讨论此同事,然后等待审核。


然后可以撤消此提交,并将文件返回到其原始状态:


 $ gunwip # git log -n 1 | grep -q -c "\-\-wip\-\-" && git reset HEAD~1 

要检查分支中是否有WIP提交,请使用以下命令:


 $ work_in_progress 

当您需要切换到相邻分支时, gwip命令是相当可靠的gwip 。 但是在Zsh中, stash本身有很多别名。


添加临时提交/重置临时提交

 $ gwip $ gunwip 


隐藏变更


您需要小心使用此命令。 可以隐藏文件,然后执行粗心操作将其完全删除,因为这里有一个reflog ,您可以在其中查找丢失的工作。


让我们用ll别名隐藏我们正在处理的文件:


 $ gsta # git stash save 

然后使用别名g it st ash p op”将它们返回:


 $ gstp # git stash pop 

或更安全的“隐藏起来”的方法是


 $ gstaa # git stash apply 

您也可以...


...看看我们到底隐藏了什么:


 gsts # git stash show --text 

...对相关命令使用缩写:


 gstc # git stash clear gstd # git stash drop gstl # git stash list 

隐藏更改/获取更改

 $ gsta $ gstaa 


寻找错误


git-bisect工具多次挽救了我的性命,也有自己的别名。 我们首先使用别名“ g it b i s s s tart”开始“二进制错误搜索”过程:


 $ gbss # git bisect start 

我们注意到,当前分支的最后一次提交包含一个错误,别名为g it b i sect b ad”


 $ gbsb # git bisect bad 

现在,我们将保证我们应用程序运行状态的提交标记为g it b i s ect ood”


 $ gbsg HEAD~20 # git bisect good HEAD~20 

现在仍然可以继续用短语gbsbgbsg回答Gita的问题,找到罪魁祸首之后,重置该过程:


 $ gbsr # git bisect reset 

我在使用此工具时确实写了这些缩写。


错误提交搜索

 $ gbss # git bisect start $ gbsb # git bisect bad $ gbsg # git bisect good $ gbsr # git bisect reset 


我们正在寻找无法无天的煽动者


即使测试的代码覆盖率很高,也没有人能够避免应用程序崩溃并友好地指向带有错误的特定行的情况。 或者,例如,在我们的情况下,我们想在a.md文件的第二行中找出谁犯了错误。 为此,运行命令:


 $ gbl a.md -L 2 # git blame -b -w a.md -L 2 

您会看到,“ Oh My Zsh贡献者不仅为git blame团队创建了别名,还为它添加了密钥,使您可以轻松地直接找到煽动者。


红利


查看提交列表


要查看提交列表,请使用git log命令和其他输出格式键。 通常,此命令以及按键会输入到Gita的自定义别名中。 幸运的是,我们已经有现成的别名glog 。 而且,如果您从本文开头的建议中安装了tig实用程序,那么您将是绝对的拥护者。


现在,要以一种非常方便的方式了解控制台中的提交历史,您需要输入单词git反之亦然:


 $ tig 

该实用程序还提供了一些有用的附加功能,这些附加功能开箱即用不在Gita中。


首先,一个搜索故事内容的命令:


 $ tig grep 

其次,查看所有源,分支,标签及其历史的列表:


 $ tig refs 

第三,也许您会发现一些有趣的事情:


 $ tig --help 

偶然使git reset --hard


您整天在elixir分支上工作:


 $ glog * 17cb385 (HEAD -> elixir) Refine Elixir article * c14b4dc Add article about Elixir * db84d54 (master) Initial commit 

最后,他们不小心删除了所有内容:


 $ grhh HEAD~2 HEAD is now at db84d54 Initial commit 

不必惊慌。 最重要的规则是停止在Gita中执行任何命令并呼气 。 本地存储库中的所有操作均记录在特殊的日志reflog日志中。 从中,您可以获取所需提交的哈希并将其还原到工作树中。


让我们看一下reflog,但不是通过git reflog的通常方式,而是通过详细的脚本更加有趣:


 $ glg -g 

找到所需的17cb385提交的哈希并恢复它:


 #           $ gcb elixir-recover 17cb385 #    $ gbd elixir #     $ gb -m elixir 

偶然地,我没有创建一个新的提交,而是对上一个进行了更改


在这里,我们再次来到救援现场。 我们会找到原始17cb385提交的哈希,如果立即取消提交,则可以使用指向HEAD@{1}的快速链接来代替查找哈希。 接下来,我们进行软重置,而索引未重置:


 #      $ grh --soft HEAD@{1} # git reset -soft #   $ gcmsg "Commit description" 

分支太旧了


有时,您开始使用某个功能,但是其发布会无限期地延迟。 您提交并切换到其他任务。 与团队一起,您对母版进行了大量更改,并在一段时间后返回具有功能的分支。 您尝试重新设置基准,但是他提供了在12次提交中解析冲突的方法。 您可以尝试解决所有问题或使其变得更容易。


让我们看一个名为elixir的功能分支的示例:


 #   master $ gcm # git checkout master #        $ gcb elixir-new # git checkout --branch elixir-new #           $ gcp elixir@{0} # git cherry-pick elixir@{0} 

因此,我们没有尝试更新分支,而是采取并转移了一个提交,而没有任何问题。


从存储库中删除重要数据


要从存储库中删除重要数据,我保存了以下代码段:


 $ git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch <path-to-your-file>' --prune-empty --tag-name-filter cat -- --all && git push origin --force --all 

运行此命令将破坏您的stash 建议在执行之前获取所有隐藏的更改。 在此处阅读有关此技术的更多信息。


引用上一个分支


当执行一些期望输入分支名称的命令时,我们可以将连字符作为对我们所伴随的分支的引用。 使用以下结帐技巧特别好:


 $ gco - # git checkout - $ gm - # git merge - $ grb - # git rebase - 

删除标记为.gitignore所有文件


另一个常见的挫折为时已晚,无法将任何不需要的文件或目录添加到.gitignore 。 为了从存储库中清理它们( 并从disk删除它们 ),已经有git clean命令的现成键:


 $ gclean -X # git clean -Xfd 

小心点!


阅读正确的方法。


为什么许多团队需要--dry-run开关?


--dry-run需要的,作为卸载和更新时的预防措施。 例如,上一节描述了如何删除.gitignore文件中指定的所有内容。 最好小心并使用--dry-run开关, --dry-run所有要删除文件--dry-run列表,然后再运行不带--dry-run的命令。


结论


本文显示了优化程序员工作的重点。 记住10-20个助记符的缩写并不困难,忘记原来的团队几乎是不可能的。 别名是标准化的,因此当您将整个团队切换到Zsh + Oh My Zsh ,即使使用结对编程,也可以以相同的速度和舒适度进行工作。


接下来要去哪里?


我提供以下选项:


  1. 最后,弄清楚Geet 在里面的排列方式 。 它有助于了解您在做什么以及为什么您想做什么不起作用。
  2. 不要懒于再次查看命令的文档: git --helpghh
  3. 请参阅链接中的完整别名列表。 试图记住它们都是疯狂的,但是将列表用作有趣的命令和键的集合是一个好主意。

某些别名不是平凡的,但在实践中证明是非常有用的。 所提供的许多别名不仅是缩写,而且是进一步优化工作的小功能。 使用Git变得更加愉快,提交的质量得到了提高。


我希望这些资料对您有用,并且您可以自己学习一些新知识。 也许他们已经开始积极引入一种新方法。 祝你好运

Source: https://habr.com/ru/post/zh-CN420529/


All Articles