Skip to contentSkip to conversation

Add ability to commit --amend

PATCH In review Jan Hudec 2 participants 2 messages Jun 15, 2016

lore
Share & tools
lore

Jan Hudec

author
#0 lore raw

PATCH 1/1 Add ability to commit --amend

Introduces separate menu entry to commit --amend. The dialog is the same, but calls commit --amend rather than just commit in the end. The stg refresh is moved here. The menu entry is always available, because user might just want to change the commit message.

---

Last summer I tried to add ability to commit --amend to qgit -- and failed because git commit didn't support --amend and -F together and rewrite using lower level plumbing started to get really ugly. Now that there is git 1.5.4 with builtin commit, which does not have this quirk, I resurrected the patch and here it is.

It seems to work for me. I didn't try any particularly nasty cases, but on the other hand I didn't change the commit logic itself, so it should not have effect on this. Please review and apply if it looks OK.

---

I have to say I don't like one thing on it---the way if(isStGITStack()) appears all over the place. Besides there is actually a bug in the detection of the stgit stack. A tree is considered to have stgit if any branch has stgit stack, even if that branch is currently checked out.

So what I'd like to look into now is introducing two classes, one for plain git core branches and one for stgit repositories. They will create the actions that depend on repository type (so they would no longer be designed, but QActions are quite simple, so I don't think it's critical). They will share code as appropriate via inheritance or delegation to current Git class. This should make the code a little more modular and make it possible if some day someone decides to add support for guilt or other git extension.

Regards,

Jan

PS: Is this the right way to submit QGit patches, or should I be using some other channel (like sf.net patch tracker or something)?

--->8---

 README             |    8 +++-
 src/commit.ui      |   16 -------
 src/commitimpl.cpp |  118 ++++++++++++++++++++++++++++++++++++++--------------
 src/commitimpl.h   |    9 +++-
 src/git.cpp        |   44 ++++++++++++++-----
 src/git.h          |    6 ++-
 src/mainimpl.cpp   |   23 +++++-----
 src/mainimpl.h     |    1 +
 src/mainview.ui    |   37 ++++++++++++++---
 9 files changed, 177 insertions(+), 85 deletions(-)
README +6 -2
index aa3c799..1fb221b 100644
@@ -227,6 +227,10 @@ In commit dialog select the files to commit or, simply, to sync with index
 (call 'git update-index' on them). A proper commit message may be entered and,
 after confirmation, changes are committed and a new revision is created.
 +
+It is also possible to amend last commit. The Edit->Amend commit opens the
+same dialog, but changes are added to the head commit instead of creating new
+commit.
++
 The core commit function is performed by 'git commit'.
 +
 TIP: It is possible to use a template for commit message, use
@@ -381,8 +385,8 @@ Integration with StGIT is implemented both by new and modified functions.
 
 .Existing functions change behavior:
 
- - Commit dialog refreshes top stack patch with modified files instead
-   of sync the cache.
+ - Amend commit dialog refreshes top stack patch with modified files instead
+   of amending the commit. It is appropriately renamed in the menu.
  - Commit dialog creates a new patch on the top of the stack filled with
    modified working directory content instead of commit a new revision to
    git repository.
src/commit.ui +0 -16
index 253ac07..3b85187 100644
@@ -286,22 +286,6 @@
  </resources>
  <connections>
   <connection>
-   <sender>pushButtonOk</sender>
-   <signal>clicked()</signal>
-   <receiver>CommitBase</receiver>
-   <slot>pushButtonOk_clicked()</slot>
-   <hints>
-    <hint type="sourcelabel" >
-     <x>20</x>
-     <y>20</y>
-    </hint>
-    <hint type="destinationlabel" >
-     <x>20</x>
-     <y>20</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
    <sender>pushButtonCancel</sender>
    <signal>clicked()</signal>
    <receiver>CommitBase</receiver>
src/commitimpl.cpp +86 -32

196 lines not on this page · raw message

src/commitimpl.h +6 -3
index 19cb156..d9e9649 100644
@@ -15,14 +15,15 @@ class Git;
 class CommitImpl : public QWidget, public Ui_CommitBase {
 Q_OBJECT
 public:
-	explicit CommitImpl(Git* git);
+	explicit CommitImpl(Git* g, bool amend);
 
 signals:
 	void changesCommitted(bool);
 
 public slots:
 	virtual void closeEvent(QCloseEvent*);
-	void pushButtonOk_clicked();
+	void pushButtonCommit_clicked();
+	void pushButtonAmend_clicked();
 	void pushButtonCancel_clicked();
 	void pushButtonUpdateCache_clicked();
 	void pushButtonSettings_clicked();
@@ -35,10 +36,12 @@ private slots:
 
 private:
 	void checkUncheck(bool checkAll);
+	bool getFiles(SList selFiles);
+	void warnNoFiles();
 	bool checkFiles(SList selFiles);
 	bool checkMsg(QString& msg);
 	bool checkPatchName(QString& patchName);
-	bool checkConfirm(SCRef msg, SCRef patchName, SCList selFiles);
+	bool checkConfirm(SCRef msg, SCRef patchName, SCList selFiles, bool amend);
 	void computePosition(int &col_pos, int &line_pos);
 
 	Git* git;
src/git.cpp +32 -12

68 lines not on this page · raw message

src/git.h +4 -2
index e795cee..d1c8b72 100644
@@ -105,6 +105,7 @@ public:
 	static const bool optOnlyLoaded  = true;
 	static const bool optDragDrop    = true;
 	static const bool optFold        = true;
+	static const bool optAmend       = true;
 	static const bool optOnlyInIndex = true;
 	static const bool optCreate      = true;
 
@@ -165,7 +166,8 @@ public:
 	bool getTree(SCRef ts, TreeInfo& ti, bool wd, SCRef treePath);
 	static const QString getLocalDate(SCRef gitDate);
 	const QString getDesc(SCRef sha, QRegExp& slogRE, QRegExp& lLogRE, bool showH, FileHistory* fh);
-	const QString getDefCommitMsg();
+	const QString getLastCommitMsg();
+	const QString getNewCommitMsg();
 	const QString getLaneParent(SCRef fromSHA, int laneNum);
 	const QStringList getChilds(SCRef parent);
 	const QStringList getNearTags(bool goDown, SCRef sha);
@@ -185,7 +187,7 @@ public:
 	QTextCodec* getTextCodec(bool* isGitArchive);
 	bool formatPatch(SCList shaList, SCRef dirPath, SCRef remoteDir = "");
 	bool updateIndex(SCList selFiles);
-	bool commitFiles(SCList files, SCRef msg);
+	bool commitFiles(SCList files, SCRef msg, bool amend);
 	bool makeTag(SCRef sha, SCRef tag, SCRef msg);
 	bool deleteTag(SCRef sha);
 	bool applyPatchFile(SCRef patchPath, bool fold, bool sign);
src/mainimpl.cpp +11 -12
index 1edb9e6..b3439d2 100644
@@ -1024,17 +1024,8 @@ void MainImpl::fileNamesLoad(int status, int value) {
 
 void MainImpl::updateCommitMenu(bool isStGITStack) {
 
-	QAction* act = NULL;
-	QList<QAction*> al(Edit->actions());
-	FOREACH (QList<QAction*>, it, al) {
-		SCRef txt = (*it)->text();
-		if (txt == "&Commit..." || txt == "Commit St&GIT patch...") {
-			act = *it;
-			break;
-		}
-	}
-	if (act)
-		act->setText(isStGITStack ? "Commit St&GIT patch..." : "&Commit...");
+	ActCommit->setText(isStGITStack ? "Commit St&GIT patch..." : "&Commit...");
+	ActAmend->setText(isStGITStack ? "Refresh St&GIT patch..." : "&Amend commit...");
 }
 
 void MainImpl::updateRecentRepoMenu(SCRef newEntry) {
@@ -1506,7 +1497,15 @@ void MainImpl::customAction_exited(const QString& name) {
 
 void MainImpl::ActCommit_activated() {
 
-	CommitImpl* c = new CommitImpl(git); // has Qt::WA_DeleteOnClose attribute
+	CommitImpl* c = new CommitImpl(git, false); // has Qt::WA_DeleteOnClose attribute
+	connect(this, SIGNAL(closeAllWindows()), c, SLOT(close()));
+	connect(c, SIGNAL(changesCommitted(bool)), this, SLOT(changesCommitted(bool)));
+	c->show();
+}
+
+void MainImpl::ActAmend_activated() {
+
+	CommitImpl* c = new CommitImpl(git, true); // has Qt::WA_DeleteOnClose attribute
 	connect(this, SIGNAL(closeAllWindows()), c, SLOT(close()));
 	connect(c, SIGNAL(changesCommitted(bool)), this, SLOT(changesCommitted(bool)));
 	c->show();
src/mainimpl.h +1 -0
index fd682ec..dd28f23 100644
@@ -101,6 +101,7 @@ protected slots:
 	void ActMailApplyPatch_activated();
 	void ActSettings_activated();
 	void ActCommit_activated();
+	void ActAmend_activated();
 	void ActTag_activated();
 	void ActTagDelete_activated();
 	void ActPush_activated();
src/mainview.ui +31 -6
index ffa8fe1..93f1d0b 100644
@@ -133,17 +133,12 @@
     <addaction name="ActExit" />
     <addaction name="separator" />
    </widget>
-   <widget class="QMenu" name="Actions" >
-    <property name="title" >
-     <string>&amp;Actions</string>
-    </property>
-    <addaction name="ActCustomActionSetup" />
-   </widget>
    <widget class="QMenu" name="Edit" >
     <property name="title" >
      <string>&amp;Edit</string>
     </property>
     <addaction name="ActCommit" />
+    <addaction name="ActAmend" />
     <addaction name="ActTag" />
     <addaction name="ActTagDelete" />
     <addaction name="ActPush" />
@@ -154,6 +149,12 @@
     <addaction name="separator" />
     <addaction name="ActSettings" />
    </widget>
+   <widget class="QMenu" name="Actions" >
+    <property name="title" >
+     <string>&amp;Actions</string>
+    </property>
+    <addaction name="ActCustomActionSetup" />
+   </widget>
    <widget class="QMenu" name="View" >
     <property name="title" >
      <string>&amp;View</string>
@@ -721,6 +722,14 @@
     <string>Show 'Select range' dialog</string>
    </property>
   </action>
+  <action name="ActAmend" >
+   <property name="text" >
+    <string>Amend comit...</string>
+   </property>
+   <property name="toolTip" >
+    <string>Amend previous comit</string>
+   </property>
+  </action>
  </widget>
  <layoutdefault spacing="6" margin="11" />
  <customwidgets>
@@ -1326,5 +1335,21 @@
     </hint>
    </hints>
   </connection>
+  <connection>
+   <sender>ActAmend</sender>
+   <signal>triggered()</signal>
+   <receiver>MainBase</receiver>
+   <slot>ActAmend_activated()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>-1</x>
+     <y>-1</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>452</x>
+     <y>238</y>
+    </hint>
+   </hints>
+  </connection>
  </connections>
 </ui>
Signature · 1 line
1.5.4.4
#1 lore raw
Quoted 5 lines · Jan Hudec

It seems to work for me. I didn't try any particularly nasty cases, but on the other hand I didn't change the commit logic itself, so it should not have effect on this. Please review and apply if it looks OK.

Patch reviewed (It seems very good) applied and pushed.

Quoted 9 lines

So what I'd like to look into now is introducing two classes, one for plain git core branches and one for stgit repositories. They will create the actions that depend on repository type (so they would no longer be designed, but QActions are quite simple, so I don't think it's critical). They will share code as appropriate via inheritance or delegation to current Git class. This should make the code a little more modular and make it possible if some day someone decides to add support for guilt or other git extension.

This does not seem an easy task (especially for the git part), of course you are more then welcomed ;-)

Quoted 4 lines

PS: Is this the right way to submit QGit patches, or should I be using some other channel (like sf.net patch tracker or something)?

Yes it is (if people on the list does not complain), I don't expect a lot of bandwidth used for qgit patches and we (possible contributors) commonly read git list, not sourceforge one.

Thanks
Marco