4

Is there a way to provide a list of files that have been edited since a previous commit or branch with helm and projectile integration?

The use case is as follows:

  1. Create feature branch feat-my-thing off of master.
  2. Modify foo.txt and bar.txt
  3. Commit changes.
  4. Days pass. Work on other things.
  5. Revisit feat-my-thing branch.
  6. I'd really like to select from a list of just foo.txt or bar.txt as those are the only files with changes since master.

For small repos, helm-projectile-find-file works well because I can usually remember what I was working on. With hundreds of files, is not as helpful especially because I'm usually only concerned with 1-5 files for a feature branch.

1 Answer 1

3

Here's a complete working solution with an example keybinding for spacemacs. The master branch is hard-coded in as the default branch to compare for file changes against. If you want to diff against the nearest parent branch you would need something like this from https://stackoverflow.com/questions/10641361

git diff --name-only <notMainDev> $(git merge-base <notMainDev> <mainDev>)

Emacs Code. This is mostly a simplification of helm-projectile-find-files and the resulting calls into projectile-current-project-files and projectile-dir-files

(defun my:helm-projectile-changed-master ()
  "Finds files changed from master in the current project."
  (interactive)
  (let ((changed-files (my:project-files-changed-from-master)))
    (if changed-files
        (helm :sources (helm-projectile-build-dwim-source changed-files)
              :buffer "*helm projectile*"
              :prompt (projectile-prepend-project-name "Find file: "))
      (message "No files have changed from master."))))

(defun my:project-files-changed-from-master ()
  "Returns a list of files changed from master in the current project."
  (cl-mapcan
  #'my:get-files-changed-from-master-in-dir
  (projectile-get-project-directories)))

(defun my:get-files-changed-from-master-in-dir (directory)
  "Returns list of files changed from master branch in DIRECTORY."
  (let* ((root (projectile-project-root))
        (default-directory directory)
        (command "git diff --name-only master")
        (changed-files (split-string
                        (projectile-shell-command-to-string command)
                        "\n"))
        (changed-files-no-empty (delete "" changed-files))
        (get-relative-project-file-name
          (lambda (file)
            (file-relative-name (expand-file-name file directory)
                                root))))
    (projectile-adjust-files
    (mapcar get-relative-project-file-name
            changed-files-no-empty))))

(spacemacs/set-leader-keys "pj" #'my:helm-projectile-changed-master)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.