使用 --patch 升级你的 git 游戏
git add --patch
我们都力求提交简洁、单一用途且有意义的提交信息。如果自上次提交以来进行了大量调试,这在实践中可能会很困难。我认识的许多人在开发和维护功能时都会使用git commit -A
或git commit .
。在进行小改动时,这没问题,但我通常不喜欢在提交超过一两行代码时使用这些选项。当我建议使用我最喜欢的 git add 选项时,很多人告诉我他们从未听说过或使用过它。
git add --patch
与其暂存所有最近的更改,不如git add --patch
(或git add -p
) 允许您将更改暂存到相关的块中。它会弹出一个交互式菜单,让您可以对暂存的更改进行精细控制。交互式界面最初会显示与输出相同的代码块git diff
。当您在交互式菜单中看到每个更改时,您可以选择y
暂存该块、n
跳过该块或s
将其拆分成更细粒度的部分。
例子
假设我正在开始一个新项目,并且我想要一个基本的用户类:
class User:
"""User class for my app"""
def __init__(self, fist_name, last_name, role):
self.first_name = fist_name
self.last_name = last_name
self.role = role
def display_name(self):
print("{} {}".format(self.fist_name, self.last_name))
def display_role(self):
print("User is a {}".format(self.role))
在我提交此代码并返回后,我注意到有几件事我想改变。
首先,我意识到我多次将“first”拼写成了“fist”,这需要更正。其次,我意识到我不喜欢在我的类中将“role”设置为字符串变量。我更希望不同的用户角色是 User 的子类。所以我将文件修改成这样。
class User:
"""Base User class for my app"""
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
def display_name(self):
print("{} {}".format(self.first_name, self.last_name))
class Admin(User):
'Admin level user'
def __init__(self, first_name, last_name, email):
super(Admin, self).__init__(first_name, last_name)
self.email = email
class Guest(User):
'Guest user'
def display_name(self):
print("Guest {} {}".format(self.first_name, self.last_name))
我想要记录两个独立的想法,所以我应该将这些更改保存在不同的提交中。git add -p
即使这两个想法出现在同一个文件中,使用 也可以轻松实现。
当我输入时,git add -p
我看到以下内容。
diff --git a/user.py b/user.py
index e0bb61a..1b59b32 100644
--- a/user.py
+++ b/user.py
@@ -1,13 +1,24 @@
class User:
- """User class for my app"""
+ """Base User class for my app"""
- def __init__(self, fist_name, last_name, role):
- self.first_name = fist_name
+ def __init__(self, first_name, last_name):
+ self.first_name = first_name
self.last_name = last_name
- self.role = role
def display_name(self):
- print("{} {}".format(fist_name, last_name))
+ print("{} {}".format(self.first_name, self.last_name))
- def display_role(self):
- print "User is a {}".format(role)
+
+class Admin(User):
+ """Admin level user"""
+
+ def __init__(self, first_name, last_name, email):
+ super(Admin, self).__init__(first_name, last_name)
+ self.email = email
+
+
+class Guest(User):
+ """Guest user"""
+
+ def display_name(self):
+ print("Guest {} {}".format(self.first_name, self.last_name))
Stage this hunk [y,n,q,a,d,/,s,e,?]?
由于我的user.py
文件相对较短,所有内容都会显示在一个大块中。我可以通过选择此s
选项将其分开。
Stage this hunk [y,n,q,a,d,/,s,e,?]? s
Split into 5 hunks.
@@ -1,3 +1,3 @@
class User:
- """User class for my app"""
+ """Base User class for my app"""
Stage this hunk [y,n,q,a,d,/,j,J,g,e,?]? n
@@ -3,4 +3,4 @@
- def __init__(self, fist_name, last_name, role):
- self.first_name = fist_name
+ def __init__(self, first_name, last_name):
+ self.first_name = first_name
self.last_name = last_name
Stage this hunk [y,n,q,a,d,/,K,j,J,g,e,?]? e
@@ -6,4 +6,3 @@
self.last_name = last_name
- self.role = role
def display_name(self):
Stage this hunk [y,n,q,a,d,/,K,j,J,g,e,?]? n
@@ -8,4 +7,4 @@
def display_name(self):
- print("{} {}".format(fist_name, last_name))
+ print("{} {}".format(self.first_name, self.last_name))
Stage this hunk [y,n,q,a,d,/,K,j,J,g,e,?]? y
@@ -11,3 +10,15 @@
- def display_role(self):
- print("User is a {}".format(role))
+
+class Admin(User):
+ """Admin level user"""
+
+ def __init__(self, first_name, last_name, email):
+ super(Admin, self).__init__(first_name, last_name)
+ self.email = email
+
+
+class Guest(User):
+ """Guest user"""
+
+ def display_name(self):
+ print("Guest {} {}".format(self.first_name, self.last_name))
Stage this hunk [y,n,q,a,d,/,K,g,e,?]? n
git commit -m "Fix typos: 'fist' -> 'first'"
[master f91e0eb] Fix typos: 'fist' -> 'first'
1 file changed, 3 insertions(+), 3 deletions(-)
通过将此文件的差异拆分为 5 个不同的块,我能够仅选择与修复fist
->first
拼写错误相关的更改,而不会影响代码的功能。
你可能会注意到一个棘手的问题:这个方法中有两个单独的修改,User.__init__()
我不希望它们出现在同一个提交中。第一个修改是更正拼写错误。第二个修改是从函数声明中fist -> first
删除参数。即使使用“hunk out”命令也无法解决这个问题,因为它们都在同一行。role
s
你会注意到,我使用了选项,而不是y
、n
或。该选项会将你带入默认的终端编辑器(可能是 vim,除非你将其更改为其他编辑器),你可以在其中手动编辑文件以反映你想要暂存的更改。保存文件并退出,你就可以通过 看到已暂存并准备提交的更改。s
e
e
git diff --cached
在这个例子中,我修改了这个块
- def __init__(self, fist_name, last_name, role):
- self.first_name = fist_name
+ def __init__(self, first_name, last_name):
+ self.first_name = first_name
在提交之前看起来像这样
- def __init__(self, fist_name, last_name, role):
- self.first_name = fist_name
+ def __init__(self, first_name, last_name, role):
+ self.first_name = first_name
我可以使用git add -p
again 来查看下次提交的更改,或者也可以使用,git add user.py
因为我知道我已经将所有剩余的更改暂存到了文件中。为了完成示例,我将使用git add -p
again。
diff --git a/user.py b/user.py
index 2a09e35..1b59b32 100644
--- a/user.py
+++ b/user.py
@@ -1,13 +1,24 @@
class User:
- """User class for my app"""
+ """Base User class for my app"""
- def __init__(self, first_name, last_name, role):
+ def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
- self.role = role
def display_name(self):
print("{} {}".format(self.first_name, self.last_name))
- def display_role(self):
- print("User is a {}".format(role))
+
+class Admin(User):
+ """Admin level user"""
+
+ def __init__(self, first_name, last_name, email):
+ super(Admin, self).__init__(first_name, last_name)
+ self.email = email
+
+
+class Guest(User):
+ """Guest user"""
+
+ def display_name(self):
+ print("Guest {} {}".format(self.first_name, self.last_name))
Stage this hunk [y,n,q,a,d,/,s,e,?]? y
git commit -m "Break user roles out into different classes."
[master dea4c79] Break user roles out into different classes.
1 file changed, 16 insertions(+), 5 deletions(-)
当我回顾我的代码时,git log
我看到了两个独立而简洁的提交。如果我决定需要撤销将 拆分成User.role
和Admin
类的提交Guest
,我不会丢失拼写错误修复。
我使用此选项将所有更改暂存以备提交,即使只有一两行。它可以帮助我发现拼写错误。我再也不用担心拼写错误修复或 delinting 与重要的功能更改混在一起了。它还能帮助我将我的想法区分开来,即使这些想法是我同时开发的。
鏂囩珷鏉ユ簮锛�https://dev.to/thejessleigh/up-your-git-game-with---patch-5d33