Git 12 岁了,送给你 12 个 Git 使用技巧

转载自 Git 12 岁了,送给你 12 个 Git 使用技巧

Git,一个分布式版本控制系统,它已经成为了开源世界的源码控制默认工具,在4月7号12岁了。但是使用Git中更另人沮丧的是,你需要了解多少才能让你更有效的使用它。同时这也是使用Git中比较美妙的一件事,因为没有什么比发现一个新的小技巧来简化或提高你的工作流的效率更加令人快乐了。

为了纪念Git的12岁生日,这篇文章提供12个诀窍与技巧来让你的Git经验更加有用和强大,从一些你可能会忽视的基础开始到一些真正的强大技巧!


1. 你的 ~/.gitconfig 文件

在第一次用git命令来提交一个仓库的修改,你可能会首先看到像下面这种内容:


*** Please tell me who you are.
Run
 git config --global user.email "you@example.com"
 git config --global user.name "Your Name"
to set your account's default identity.

你可能还没有意识到那些命令正在修改~/.gitconfig文件的内容,这个文件就是Git存储全局配置选项的文件。通过你的~/.gitconfig文件你可要做很多事情,包括定义别名,永久的打开(或关闭)一些特定的命令选项,还可以修改Git如何工作的方面(例如:git diff使用哪个diff算法,或者默认使用什么类型的的合并策略)。你甚至可以按条件地基于路径包含其他配置文件到一个仓库!使用“man git-config”查看所有细节。

2. 你的仓库的.gitconfig文件

在之前的技巧中,你可能会想知道在git config 命令中的—global标识是做什么的。它告诉Git更新“global”配置,也就是~/.gitconfig发现的这个配置。当然,拥有一个全局的配置代表了一个本地配置,而且足够肯定的是,如果你省略—global选项,git config 会更新这个仓库自己的配置,这个配置文件存储在.git/config。

在.git/config中设置的选项会推翻在~/.gitconfig文件中的对应设置。因此,例如,如果你需要在一个特定的仓库中使用一个不同的邮箱地址,你可以运行“git config user.email "also_you@example.com"”。然后,你在这个仓库中提交会使用你单独配置的这个邮箱地址。如果你使用一个工作的电脑在开源项目中工作,但是希望在这个项目中使用个人的邮箱地址,而其他在主Git配置中仍然使用工作邮箱,这一点是非常有用的。

在~/.gitconfig中可以设置的任何东西,都可以在.git/config中设置来对这个仓库做特定设置。在下面的这些技巧中,当我提到在你的~/.gitconfig文件中添加什么东西,同时也说明可以在特定的仓库的.git/config中添加来设置那个选项。

3、别名

别名是你可以在你的~/.gitconfig文件里做的另外一件事。他的工作原理就像shell命令行里的别名——设置一个新的命令名称来调用一个或者多个其他的命令,这些命令通常包括一些特定的选项或标识。别名对于你经常使用的那些又长又复杂的命令行是非常有效的。

你可以使用git config命令来定义别名——例如,执行”git config —global —add alias.st status”命令后,会使得执行git st与执行git status做的是同样的事情——然而,我发现当定义别名的时候,只需要直接在~/.gitconfig文件里编辑通常会更加容易。

如果你选择这么做,你会发现~/.gitconfig文件就是一个INI文件,INI是一种带有特定段落的基础键值对文件格式。添加一个别名时,你将改变[alias]段落。例如:上面提到的定义相同的git st别名,需要添加下面这段代码:


[alias]
st = status

(如果已经有了[alias]这个段落,只需要在这个段落中添加到第二行)

4. shell命令中的别名

别名不仅仅是运行其他Git子命令——你也可以定义别名,这些别名可以运行其他shell命令。这是一个很好的方法来处理一个重复的、罕见的、复杂的任务:一旦你已经想到第一次怎么做,那就使用一个别名保存这个命令。例如,我有几个仓库是我fork了一个开源项目,而且在本地做了一些修改,这些修改不用贡献给这个项目。在项目的持续的开发的过程中我想保持最新的版本,同时保留我的本地修改。为了完成这个想法,我需要定期地从upstream仓库中合并这些修改到我的fork——我定义一个别名“upstream-merge”来完成这个操作。定义如下:


upstream-merge = !"git fetch origin -v && git fetch upstream -v && git merge upstream/master && git push"

别名定义开始的这个“!”是告诉Git来通过shell运行这个命令。这个例子包括了运行一些git命令,但是使用这种方式定义别名可以运行任何shell命令。

(注意:如果你想复制我的upstream-merge别名,你将需要确认你有一个Git remote命名为upstream来指定这个你fork的upstream仓库。你可以通过“git remote add upstream ”来添加一个。)

5. 可视化提交图

如果你从事的是一个有很多分支活动的项目,有时可能很难掌握所有正在发生的工作以及它们之间的相关性。各种GUI工具可让你弄清楚不同分支的概况以及在所谓的“提交图”中提交记录。例如,以下是我使用 GitLab 提交图查看器进行可视化的一个存储卡的部分截图:

John Anderson, CC BY

如果你是专注于命令行的用户,就可以不在多个工具之间切换导致分心,这个工具在命令行上实现了类似图形界面的提交视图。通过 -- graph 参数获取 git 的记录: 

John Anderson, CC BY

下面的命令可以得到一样的仓库可视化片段:


git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative

--graph 选项将图表添加到日志的左侧, --abbrev-commit 存储提交使用了 SHA 方法, --date=relative 表达式用相对的术语来表示日期,并且 --pretty 以 bit 格式处理自定义格式。我知道 git lg 的别名,它是我最常运行的10个命令之一。

6. 更优雅的强制推送(force-push)

有时,就跟你尽量避免使用它一样困难的是,你会发现你需要运行 git push --force 来覆写你仓库的远程副本上的历史记录。你可能已得到了一些反馈,他们会要求你进行交互式的变基(rebase),或者你可能已经搞砸了,并且希望隐藏证据。

当他人在仓库的远程副本的同一分支上进行改动后,会发生强制推送的风险。当你强制推送已重写的历史记录时,某些提交将会丢失。这是 git push --force-with-lease 出现的原因 - 如果远程分支已更新,它不会允许你执行强制推送,这将确保你不会丢弃他人的工作。

7. git add -N

你是否使用过git commit -a在一次行动中提交你所有未完成的修改,只有在你push完你的提交后才发现git commit -a忽略了新添加的文件?解决这个问题你可以用git add -N(“通知”)来告诉Git你想把新添加的文件包含在提交中在你第一次实际提交之前。

8. git add -p

一最佳的实践为当使用Git时确保每个提交只包含一个逻辑更改--不管是修复一个bug还是(实现)一个新功能。然而, 有时当你工作 ,会在你的仓库中出现一个以上的修改 提交 。你怎么样把事情分开,使每个提交只包含适当的修改呢?git add --patch来解救!

这个标志将会使git add命令查看你工作副本中所有的变更,询问你是否愿意将它提交,跳过,或者推迟决定(还有其他一些更强大的选项,你可以通过在运行这命令后选择?来查看)。git add -p是一个神奇的工具来生产结构良好的提交。

9. git checkout -p

与 git add -p类似,git checkout命令将使用 --patch 或 -p 选项,这会使 git 在本地工作副本中展示每个“大块”的改动,并允许丢弃对应改动 —— 简单地说就是恢复本地工作副本到你改变之前的状态。

某些场景下这非常有用,例如,在你跟踪一个 bug 时引入了一堆调试日志语句,在修正了这个 bug 之后,你可以先使用 git checkout -p 删除所有新加的调试日志,之后使用 git add -p 来添加 bug 修复。没有比组合一个极好的、结构良好的提交更令人满意的了

10. Rebase with command execution

有些项目有一条规则,即存储库中的每个提交都必须处于可工作状态 - 也就是说,在每次提交时,代码应该是可编译的,或运行测试套件应该不会失败的。当你在某分支上工作时间长时,但如果你最终因为某种原因需要rebase时,那么跳过每个变基后的提交以确保你没有意外引入一个中断是有些冗长乏味的。

幸运的是,git rebase已经支持了-x或--exec选项。git rebase -x 将在每次提交应用到rebase后运行该命令。因此,例如,如果你有一个项目,其中npm run tests会运行你的测试套件,那么在rebase期间应用每次提交后,git rebase -x npm run tests将会运行测试套件。这使你可以查看测试套件是否在任何变基后的提交中有失败情况,因此你可以确保测试套件在每次提交时仍能通过。

11. 基于时间修改的指南

很多Git子命令都接受一个修正的参数来决定命令作用于仓库的哪个部分,可能是某次特定的提交的 sha1 值,或者一个分支的名称,又或者是一个符号性的名称如 HEAD(代表当前检出分支最后一次的提交),除了这些简单的形式以外,你还可以附加一个指定的日期或时间作为参数,表示“这个时间的引用”。

这个功能在某些时候会变得十分有用,比如当你处理最新出现的 bug,自言自语道:“这个功能明明昨天还是好好的,到底又改了些什么”,不用盯着满屏的 git 日志的输出试图弄清楚什么时候更改了提交,您只需运行 git diff HEAD@{yesterday},会看到从昨天以来的所有修改,这也适用于较长的时间段(例如 git diff HEAD@{'2 months ago'}) ,以及一个确切的日期(例如git diff HEAD@{'2010-01-01 12:00:00'})。

您还可以将这些基于日期的修改参数与使用修正参数的任何 Git 子命令一起使用。在 gitrevisions 手册页中有关于具体使用哪种格式的详细信息。

12. 全知的 reflog

你是不是试过在 rebase 时干掉过某次提交,后来又发现你需要保留这次提交的一些东西?你可能觉得这些提交的东西已经永远找不回来了,只能从头再来了。其实不然,但如果你在本地工作副本中提交了,提交就会进入到 "引用日志" ,你仍然可以访问到。

运行 git reflog 将在本地工作副本中显示当前分支的所有活动的列表,并为您提供每个提交的 SHA1 值。一旦发现你 rebase 时放弃的那个提交,你可以运行 git checkout 来检出该次提交,复制好你需要的信息,然后再运行 git checkout HEAD 返回到分支最新的提交去。

希望这些技巧中至少有一个能教你一些关于 Git 的新知识,Git 已经 12 岁了,在这个持续创新,不断添加新特性的项目里,你最喜欢哪个技巧?



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/330320.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

转:Kafka、RabbitMQ、RocketMQ等消息中间件的介绍和对比

转自&#xff1a; https://blog.csdn.net/yunfeng482/article/details/72856762 前言 在分布式系统中,我们广泛运用消息中间件进行系统间的数据交换,便于异步解耦。现在开源的消息中间件有很多,前段时间产品 RocketMQ (MetaQ的内核) 也顺利开源,得到大家的关注。 概念 MQ简…

微信小程序定时器setInterval()的使用注意事项

setInterval&#xff08;function(){}, number 时间间隔/ms&#xff09; 注意在setInterval中定义的函数中使用 this 指向的是该计时器&#xff0c;若要用到页面数据应如下操作&#xff1a; let thatthis setInterval(function(){ that.data.a0; },number 时间间隔/ms) …

图解分布式架构的演进

转载自 图解分布式架构的演进一、什么是分布式架构分布式系统&#xff08;distributed system&#xff09; 是建立在网络之上的软件系统。内聚性&#xff1a;是指每一个数据库分布节点高度自治&#xff0c;有本地的数据库管理系统。透明性&#xff1a;是指每一个数据库分布节点…

转:微服务架构:BFF和网关是如何演化出来的?(这篇文章相当棒)

转自&#xff1a; https://juejin.im/entry/6844903806208049159 这篇文章写得非常棒&#xff0c;从服务&#xff0c;到bff&#xff0c; 到gateway 的一步步演化&#xff0c;描述的非常清晰易懂。 1、介绍 BFF(Backend for Frontend)和网关Gateway是微服务架构中的两个重要概…

微信小程序的坑

<input>组件后台接受到的是字符串类型&#xff0c;若要用数字类型应用Number()进行转化 微信小程序中许多API会是页面的 this 转向应注意用 let that this 来获取页面的指针&#xff01;

实现滚到div时淡入效果

首先实现淡入的动画 CSS代码如下&#xff1a; keyframes float { from { position: relative; margin-top:200px; opacity: 0; } to { position: relative; margin-top: 50px; opacity: 1; } } 接下来用JS判断当前滚动的位置并加入…

高级 Java 面试通关知识点整理

转载自 高级 Java 面试通关知识点整理1、常用设计模式单例模式&#xff1a;懒汉式、饿汉式、双重校验锁、静态加载&#xff0c;内部类加载、枚举类加载。保证一个类仅有一个实例&#xff0c;并提供一个访问它的全局访问点。代理模式&#xff1a;动态代理和静态代理&#xff0c;…

windows查找端口占用并杀死端口进程

tasklist 查看进程netstat -ano|findstr "8080" 查找端口 8080 占用信息&#xff1b; tasklist|findstr 7176 查找进程id为 7176的进程信息&#xff1b; taskkill /F /PID 7176 杀死进程7176

Angular项目打包到nginx部署过程

Angular项目打包到nginx部署过程 一. 打包Angluar ng build,会在项目文件夹下生成dist文件&#xff0c;里面是打包后的文件 二. 部署nginx 在nginx官网中下载nginx 把dist文件夹下的打包文件拷贝到nginx/html下并重命名为myProj 修改conf/nginx.conf文件 location / {root…

SpringMVC表单验证器的使用

转载自 SpringMVC表单验证器的使用本章讲解SpringMVC中怎么通过注解对表单参数进行验证。 SpringBoot配置 使用springboot&#xff0c; spring-boot-starter-web会自动引入 hiberante-validator, validation-api依赖。 在 WebMvcConfigurerAdapter实现类里面添加验证器及国际化…

转-Kafka【第一篇】Kafka集群搭建

转自&#xff1a; https://www.cnblogs.com/luotianshuai/p/5206662.html Kafka【第一篇】Kafka集群搭建 Kafka初识 1、Kafka使用背景 在我们大量使用分布式数据库、分布式计算集群的时候&#xff0c;是否会遇到这样的一些问题&#xff1a; 我们想分析下用户行为&#xf…

Angular 应用解决跨域访问的问题

设置反向代理 原理是设置反向代理服务器&#xff0c;让 Angular 应用都访问自己的服务器中的API&#xff0c;而这类API都会被反向代理服务器转发到 Java 服务API中&#xff0c;而这个过程对于 Angular 应用是无感知的。 业界经常是采用 NGINX 服务来承担反向代理的职责。而在 …

57张PPT彻底搞清楚区块链技术。。

转载自 57张PPT彻底搞清楚区块链技术。。

如何基于tomcat构建web站点

修改 conf/server.xml 配置&#xff0c; 如下&#xff1a; <Server port"8005" shutdown"SHUTDOWN"><Service name"Catalina111"><Connector port"8080" protocol"HTTP/1.1"connectionTimeout"20000&q…

小程序实现圆饼图

效果图 预备知识 CanvasContext.createCircularGradient(number x, number y, number r) 创建一个圆形的渐变颜色。起点在圆心&#xff0c;终点在圆环。返回的CanvasGradient对象需要使用 CanvasGradient.addColorStop() 来指定渐变点&#xff0c;至少要两个。&#xff08;详细…

一分钟开启Tomcat https支持

转载自 一分钟开启Tomcat https支持1、修改配置文件 打开tomcat/conf/server.xml配置文件&#xff0c;把下面这段配置注释取消掉&#xff0c; keystorePass为证书密钥需要手动添加&#xff0c;创建证书时指定的。 <Connector port"8443" protocol"org.apache…

转:在eclipse中搭建maven工程(第二种方法)

转自 &#xff1a; https://blog.csdn.net/bug_moving/article/details/54178092&#xff1b; 第一种方法见前面的博客 用Maven创建web项目&#xff08;详细步骤&#xff09; maven-3.3.9 下载之后就是配置环境变量&#xff0c;可以去百度一哈&#xff0c;用MAVEN_HOME配置…

Spring Boot - Profile不同环境配置

转载自 Spring Boot - Profile不同环境配置Profile是什么 Profile我也找不出合适的中文来定义&#xff0c;简单来说&#xff0c;Profile就是Spring Boot可以对不同环境或者指令来读取不同的配置文件。 Profile使用 假如有开发、测试、生产三个不同的环境&#xff0c;需要定义三…

Java Springboot应用部署

流程&#xff1a; 在pom.xml中加入以下配置 (引入springboot打包插件 spring-boot-maven-plugin ): <project ...><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin<…

转:Tomcat启动失败 提示Server Tomcat v7.0 Server at localhost failed to start.六种解决方法

转&#xff1a;https://my.oschina.net/u/4391471/blog/3298034 Tomcat启动失败&#xff0c;提示Server Tomcat v7.0 Server at localhost failed to start 在一次查看自己以前写过的项目中&#xff0c;运行tomcat失败&#xff0c;出现如图提示 然而自己之前的项目运行时候都…