From 6fc4b1e9945574a12bdb8e2b3416205e4dbc38f4 Mon Sep 17 00:00:00 2001 From: Kyle Harrington Date: Wed, 22 Sep 2021 10:52:56 +0200 Subject: [PATCH 1/4] Add gac-automatically-pull-p support --- README.org | 9 ++++++++- git-auto-commit-mode.el | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/README.org b/README.org index 0c78480..44193a8 100644 --- a/README.org +++ b/README.org @@ -3,7 +3,7 @@ * NAME - git-auto-commit-mode - Emacs minor mode to automatically commit (and + git-auto-commit-mode - Emacs minor mode to automatically commit (and pull and push) a git repository. [[http://melpa.org/#/git-auto-commit-mode][file:http://melpa.org/packages/git-auto-commit-mode-badge.svg]] @@ -26,6 +26,8 @@ When enabled, git-auto-commit-mode uses the =after-save-hook= to commit changes to git each time. If =gac-automatically-push-p= is non-nil it also tries to push the ~HEAD~ to the current upstream. + If =gac-automatically-pull-p= is + non-nil it also tries to pull the ~HEAD~ to the current upstream. Making sure that upstream is properly set is the responsibility of the user. @@ -82,6 +84,11 @@ push the git repository's ~HEAD~ to its default upstream. Setting up the upstream is the user's responsibility. + - =gac-automatically-pull-p= :: + A boolean value indicating whether or not git-auto-commit-mode should try to + pull the git repository's ~HEAD~ from its default upstream. Setting up the + upstream is the user's responsibility. + - =gac-automatically-add-new-files-p= :: A boolean value indicating whether or not git-auto-commit-mode should add new (untracked) files to the repository. diff --git a/git-auto-commit-mode.el b/git-auto-commit-mode.el index eaeda3a..2980344 100644 --- a/git-auto-commit-mode.el +++ b/git-auto-commit-mode.el @@ -29,6 +29,9 @@ ;; When `gac-automatically-push-p' is non-nil, it also tries to push ;; to the current upstream. +;; When `gac-automatically-pull-p' is non-nil, it also tries to pull +;; from the current upstream. + ;; When `gac-debounce-interval' is non-nil and set to a number ;; representing seconds, it will only perform Git actions at that ;; interval. That way, repeatedly saving a file will not hammer the @@ -52,6 +55,16 @@ If non-nil a git push will be executed after each commit." :risky t) (make-variable-buffer-local 'gac-automatically-push-p) +(defcustom gac-automatically-pull-p nil + "Automatically pull before each commit. + +If non-nil a git pull will be executed before each commit." + :tag "Automatically pull" + :group 'git-auto-commit-mode + :type 'boolean + :risky t) +(make-variable-buffer-local 'gac-automatically-pull-p) + (defcustom gac-automatically-add-new-files-p t "Should new (untracked) files automatically be committed to the repo?" :tag "Automatically add new files" @@ -197,6 +210,21 @@ should already have been set up." (set-process-sentinel proc 'gac-process-sentinel) (set-process-filter proc 'gac-process-filter)))) +(defun gac-pull (buffer) + "Pull commits from the current upstream. + +This doesn't check or ask for a remote, so the correct remote +should already have been set up." + ;; gac-pull is currently only called from gac--after-save, where it is wrapped + ;; in with-current-buffer, which should already take care of + ;; default-directory. The explicit binding here is defensive, in case gac-pull + ;; starts being used elsewhere. + (let ((default-directory (file-name-directory (buffer-file-name buffer)))) + (let ((proc (start-process "git" "*git-auto-pull*" "git" "pull"))) + (set-process-sentinel proc 'gac-process-sentinel) + (set-process-filter proc 'gac-process-filter)))) + + (defvar gac--debounce-timers (make-hash-table :test #'equal)) (defun gac--debounced-save () @@ -233,6 +261,11 @@ should already have been set up." (or (and gac-automatically-add-new-files-p (not (gac--buffer-is-tracked buffer))) (gac--buffer-has-changes buffer))) + (with-current-buffer buffer + ;; with-current-buffer required here because gac-automatically-pull-p + ;; is buffer-local + (when gac-automatically-pull-p + (gac-pull buffer))) (gac-commit buffer) (with-current-buffer buffer ;; with-current-buffer required here because gac-automatically-push-p @@ -252,6 +285,8 @@ should already have been set up." (defun gac-after-save-func () "Commit the current file. +When `gac-automatically-pull-p' is non-nil also pull. + When `gac-automatically-push-p' is non-nil also push." (if gac-debounce-interval (gac--debounced-save) @@ -260,7 +295,7 @@ When `gac-automatically-push-p' is non-nil also push." ;;;###autoload (define-minor-mode git-auto-commit-mode "Automatically commit any changes made when saving with this -mode turned on and optionally push them too." +mode turned on, optionally pull and push them too." :lighter " ga" (if git-auto-commit-mode (add-hook 'after-save-hook 'gac-after-save-func t t) From cc7871984466902390b30fd7c9a2cbd6802c3b90 Mon Sep 17 00:00:00 2001 From: Kyle Harrington Date: Wed, 22 Sep 2021 11:12:22 +0200 Subject: [PATCH 2/4] Setup auto pull to run in a before-save-hook --- git-auto-commit-mode.el | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/git-auto-commit-mode.el b/git-auto-commit-mode.el index 2980344..96355d3 100644 --- a/git-auto-commit-mode.el +++ b/git-auto-commit-mode.el @@ -8,6 +8,9 @@ ;; Keywords: vc ;; URL: https://github.com/ryuslash/git-auto-commit-mode +;; Updates by: Kyle Harrington +;; Updated: Sept 22, 2021 + ;; This file is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License ;; as published by the Free Software Foundation; either version 3 @@ -215,7 +218,7 @@ should already have been set up." This doesn't check or ask for a remote, so the correct remote should already have been set up." - ;; gac-pull is currently only called from gac--after-save, where it is wrapped + ;; gac-pull is currently only called from gac--before-save, where it is wrapped ;; in with-current-buffer, which should already take care of ;; default-directory. The explicit binding here is defensive, in case gac-pull ;; starts being used elsewhere. @@ -261,11 +264,6 @@ should already have been set up." (or (and gac-automatically-add-new-files-p (not (gac--buffer-is-tracked buffer))) (gac--buffer-has-changes buffer))) - (with-current-buffer buffer - ;; with-current-buffer required here because gac-automatically-pull-p - ;; is buffer-local - (when gac-automatically-pull-p - (gac-pull buffer))) (gac-commit buffer) (with-current-buffer buffer ;; with-current-buffer required here because gac-automatically-push-p @@ -274,10 +272,24 @@ should already have been set up." (gac-push buffer)))) (remhash buffer gac--debounce-timers))) +(defun gac--before-save (buffer) + (unwind-protect + (when (and (buffer-live-p buffer) + (or (and gac-automatically-add-new-files-p + (not (gac--buffer-is-tracked buffer))) + (gac--buffer-has-changes buffer))) + (with-current-buffer buffer + ;; with-current-buffer required here because gac-automatically-pull-p + ;; is buffer-local + (when gac-automatically-pull-p + (gac-pull buffer)))) + (remhash buffer gac--debounce-timers))) + (defun gac-kill-buffer-hook () (when (and gac-debounce-interval gac--debounce-timers (gethash (current-buffer) gac--debounce-timers)) + (gac--before-save (current-buffer)) (gac--after-save (current-buffer)))) (add-hook 'kill-buffer-hook #'gac-kill-buffer-hook) @@ -285,21 +297,29 @@ should already have been set up." (defun gac-after-save-func () "Commit the current file. -When `gac-automatically-pull-p' is non-nil also pull. - When `gac-automatically-push-p' is non-nil also push." (if gac-debounce-interval (gac--debounced-save) (gac--after-save (current-buffer)))) +(defun gac-before-save-func () + "Commit the current file. + +When `gac-automatically-pull-p' is non-nil also pull." + (gac--before-save (current-buffer))) + ;;;###autoload (define-minor-mode git-auto-commit-mode "Automatically commit any changes made when saving with this mode turned on, optionally pull and push them too." :lighter " ga" (if git-auto-commit-mode - (add-hook 'after-save-hook 'gac-after-save-func t t) - (remove-hook 'after-save-hook 'gac-after-save-func t))) + (progn + (add-hook 'before-save-hook 'gac-before-save-func t t) + (add-hook 'after-save-hook 'gac-after-save-func t t)) + (progn + (remove-hook 'before-save-hook 'gac-before-save-func t) + (remove-hook 'after-save-hook 'gac-after-save-func t)))) (provide 'git-auto-commit-mode) From 78a20efb2f814ff572923e5080bb47b2a704a16e Mon Sep 17 00:00:00 2001 From: Kyle Harrington Date: Thu, 7 Oct 2021 10:20:58 +0200 Subject: [PATCH 3/4] Fix conditions for before-save check --- git-auto-commit-mode.el | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/git-auto-commit-mode.el b/git-auto-commit-mode.el index 96355d3..1e1a2dc 100644 --- a/git-auto-commit-mode.el +++ b/git-auto-commit-mode.el @@ -274,10 +274,7 @@ should already have been set up." (defun gac--before-save (buffer) (unwind-protect - (when (and (buffer-live-p buffer) - (or (and gac-automatically-add-new-files-p - (not (gac--buffer-is-tracked buffer))) - (gac--buffer-has-changes buffer))) + (when (buffer-live-p buffer) (with-current-buffer buffer ;; with-current-buffer required here because gac-automatically-pull-p ;; is buffer-local From 519f07efd1c8f80ed02d5e252658ffb257db9960 Mon Sep 17 00:00:00 2001 From: Kyle Harrington Date: Thu, 11 Nov 2021 10:40:13 +0900 Subject: [PATCH 4/4] Handle git merges, run git pull/push synchronously in new thread --- git-auto-commit-mode.el | 54 ++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 36 deletions(-) diff --git a/git-auto-commit-mode.el b/git-auto-commit-mode.el index 1e1a2dc..215cdf0 100644 --- a/git-auto-commit-mode.el +++ b/git-auto-commit-mode.el @@ -209,23 +209,20 @@ should already have been set up." ;; default-directory. The explicit binding here is defensive, in case gac-push ;; starts being used elsewhere. (let ((default-directory (file-name-directory (buffer-file-name buffer)))) - (let ((proc (start-process "git" "*git-auto-push*" "git" "push"))) - (set-process-sentinel proc 'gac-process-sentinel) - (set-process-filter proc 'gac-process-filter)))) + (call-process "git" nil "*git-auto-push*" nil "push"))) (defun gac-pull (buffer) "Pull commits from the current upstream. - This doesn't check or ask for a remote, so the correct remote should already have been set up." - ;; gac-pull is currently only called from gac--before-save, where it is wrapped + ;; gac-pull is currently only called from gac--after-save, where it is wrapped ;; in with-current-buffer, which should already take care of ;; default-directory. The explicit binding here is defensive, in case gac-pull ;; starts being used elsewhere. (let ((default-directory (file-name-directory (buffer-file-name buffer)))) - (let ((proc (start-process "git" "*git-auto-pull*" "git" "pull"))) - (set-process-sentinel proc 'gac-process-sentinel) - (set-process-filter proc 'gac-process-filter)))) + (call-process "git" nil "*git-auto-pull*" nil "merge" "--squash") + (call-process "git" nil "*git-auto-pull*" nil "commit" "--no-edit") + (call-process "git" nil "*git-auto-pull*" nil "pull" "--rebase"))) (defvar gac--debounce-timers (make-hash-table :test #'equal)) @@ -265,28 +262,23 @@ should already have been set up." (not (gac--buffer-is-tracked buffer))) (gac--buffer-has-changes buffer))) (gac-commit buffer) - (with-current-buffer buffer - ;; with-current-buffer required here because gac-automatically-push-p - ;; is buffer-local - (when gac-automatically-push-p - (gac-push buffer)))) - (remhash buffer gac--debounce-timers))) - -(defun gac--before-save (buffer) - (unwind-protect - (when (buffer-live-p buffer) - (with-current-buffer buffer - ;; with-current-buffer required here because gac-automatically-pull-p - ;; is buffer-local - (when gac-automatically-pull-p - (gac-pull buffer)))) + (make-thread + (lambda () + (with-current-buffer buffer + ;; with-current-buffer required here because gac-automatically-pull-p + ;; is buffer-local + (when gac-automatically-pull-p + (gac-pull buffer)) + ;; with-current-buffer required here because gac-automatically-push-p + ;; is buffer-local + (when gac-automatically-push-p + (gac-push buffer)))))) (remhash buffer gac--debounce-timers))) (defun gac-kill-buffer-hook () (when (and gac-debounce-interval gac--debounce-timers (gethash (current-buffer) gac--debounce-timers)) - (gac--before-save (current-buffer)) (gac--after-save (current-buffer)))) (add-hook 'kill-buffer-hook #'gac-kill-buffer-hook) @@ -299,24 +291,14 @@ When `gac-automatically-push-p' is non-nil also push." (gac--debounced-save) (gac--after-save (current-buffer)))) -(defun gac-before-save-func () - "Commit the current file. - -When `gac-automatically-pull-p' is non-nil also pull." - (gac--before-save (current-buffer))) - ;;;###autoload (define-minor-mode git-auto-commit-mode "Automatically commit any changes made when saving with this mode turned on, optionally pull and push them too." :lighter " ga" (if git-auto-commit-mode - (progn - (add-hook 'before-save-hook 'gac-before-save-func t t) - (add-hook 'after-save-hook 'gac-after-save-func t t)) - (progn - (remove-hook 'before-save-hook 'gac-before-save-func t) - (remove-hook 'after-save-hook 'gac-after-save-func t)))) + (add-hook 'after-save-hook 'gac-after-save-func t t) + (remove-hook 'after-save-hook 'gac-after-save-func t))) (provide 'git-auto-commit-mode)