diff --git a/magit.el b/magit.el index ca8bc2b9..80d9e584 100644 --- a/magit.el +++ b/magit.el @@ -779,7 +779,7 @@ Many Magit faces inherit from this one by default." ;; We define individual functions (instead of using lambda etc) so ;; that the online help can show something meaningful. -(magit-define-section-jumper unpulled "Unpulled commits") +(magit-define-section-jumper untracked "Untracked files") (magit-define-section-jumper unstaged "Unstaged changes") (magit-define-section-jumper staged "Staged changes") (magit-define-section-jumper unpushed "Unpushed commits") @@ -790,7 +790,7 @@ Many Magit faces inherit from this one by default." (define-key map (kbd "n") 'magit-goto-next-section) (define-key map (kbd "p") 'magit-goto-previous-section) (define-key map (kbd "TAB") 'magit-cycle-section) - (define-key map (kbd "1") 'magit-jump-to-unpulled) + (define-key map (kbd "1") 'magit-jump-to-untracked) (define-key map (kbd "2") 'magit-jump-to-unstaged) (define-key map (kbd "3") 'magit-jump-to-staged) (define-key map (kbd "4") 'magit-jump-to-unpushed) @@ -801,6 +801,8 @@ Many Magit faces inherit from this one by default." (define-key map (kbd "u") 'magit-unstage-item) (define-key map (kbd "U") 'magit-unstage-all) (define-key map (kbd "i") 'magit-ignore-item) + (define-key map (kbd "I") 'magit-ignore-item-locally) + (define-key map (kbd "i") 'magit-ignore-item) (define-key map (kbd "?") 'magit-describe-item) (define-key map (kbd ".") 'magit-mark-item) (define-key map (kbd "=") 'magit-diff-with-mark) @@ -864,6 +866,7 @@ Many Magit faces inherit from this one by default." ["Revert" magit-revert-item t] "---" ["Ignore" magit-ignore-item t] + ["Ignore locally" magit-ignore-item-locally t] ["Discard" magit-discard-item t] ["Reset head" magit-reset-head t] ["Reset working tree" magit-reset-working-tree t] @@ -1019,6 +1022,27 @@ Please see the manual for a complete description of Magit. (interactive) (magit-for-all-buffers #'magit-refresh-buffer default-directory)) +;;; Untracked files + +(defun magit-wash-untracked-file () + (if (looking-at "^? \\(.*\\)$") + (let ((file (match-string-no-properties 1))) + (delete-region (point) (+ (line-end-position) 1)) + (magit-with-section file 'file + (magit-set-section-info file) + (insert "\t" file "\n")) + t) + nil)) + +(defun magit-wash-untracked-files () + (magit-wash-sequence #'magit-wash-untracked-file)) + +(defun magit-insert-untracked-files () + (magit-insert-section 'untracked "Untracked files:" + 'magit-wash-untracked-files + magit-collapse-threshold + "git" "ls-files" "-t" "--others" "--exclude-standard")) + ;;; Diffs and Hunks (defun magit-diff-line-file () @@ -1200,7 +1224,7 @@ Please see the manual for a complete description of Magit. (let ((magit-hide-diffs t)) (magit-insert-section 'unstaged title 'magit-wash-diffs magit-collapse-threshold - "sh" "-c" "git ls-files -t --others --exclude-standard; git diff"))) + "git" "diff"))) (defun magit-insert-staged-changes () (let ((magit-hide-diffs t)) @@ -1330,6 +1354,7 @@ Please see the manual for a complete description of Magit. (if rebase (insert (apply 'format "Rebasing: %s (%s of %s)\n" rebase)))) (insert "\n") + (magit-insert-untracked-files) (magit-insert-pending-changes) (magit-insert-pending-commits) (when remote @@ -1361,7 +1386,7 @@ Please see the manual for a complete description of Magit. "Add the item at point to the staging area." (interactive) (magit-section-action (item info "stage") - ((unstaged file) + ((untracked file) (magit-run "git" "add" info)) ((unstaged diff hunk) (if (magit-hunk-item-is-conflict-p item) @@ -1962,18 +1987,29 @@ Prefix arg means justify as well." ;;; Miscellaneous +(defun magit-ignore-file (file edit local) + (let ((ignore-file (if local ".git/info/exclude" ".gitignore"))) + (if edit + (setq file (read-string "File to ignore: " file))) + (append-to-file (concat "/" file "\n") nil ignore-file) + (magit-need-refresh))) + (defun magit-ignore-item () (interactive) (magit-section-action (item info "ignore") - ((unstaged file) - (append-to-file (concat "/" info "\n") - nil ".gitignore") - (magit-need-refresh)))) + ((untracked file) + (magit-ignore-file info current-prefix-arg nil)))) + +(defun magit-ignore-item-locally () + (interactive) + (magit-section-action (item info "ignore") + ((untracked file) + (magit-ignore-file info current-prefix-arg t)))) (defun magit-discard-item () (interactive) (magit-section-action (item info "discard") - ((unstaged file) + ((untracked file) (if (yes-or-no-p (format "Delete %s? " info)) (magit-run "rm" info))) ((unstaged diff hunk) @@ -2002,7 +2038,7 @@ Prefix arg means justify as well." (defun magit-visit-item () (interactive) (magit-section-action (item info "visit") - ((unstaged file) + ((untracked file) (find-file info)) ((diff) (find-file (magit-diff-item-file item))) diff --git a/magit.texi b/magit.texi index 2762e30c..96bf2e36 100644 --- a/magit.texi +++ b/magit.texi @@ -104,6 +104,8 @@ states of the section: fully visible, fully hidden (expect for the first line), and collapsed, where only the first lines of the children are visible. You can also control the visibility of sub-sections in this way. +The first section shows @emph{Untracked files}, if there are any. See +@ref{Untracked files} for more details. Two section show your local changes. They are explained fully in the next chapter, @ref{Staging and Committing}. @@ -113,12 +115,25 @@ status buffer shows the differences between the current branch and the tracking branch. See @ref{Pushing and Pulling} for more information. Typing a digit in the status buffer will move point to a section -header: @kbd{1} will move to @emph{Unpulled commits}, @kbd{2} will move +header: @kbd{1} will move to @emph{Untracked files}, @kbd{2} will move to @emph{Unstaged changes} or @emph{Changes}, @kbd{3} will move to @emph{Staged changes}, and @kbd{4} will move to @emph{Unpushed commits}. Note that these relations are fixed, @kbd{3} always moves to @emph{Unstaged changes}, not the third visible section. +@node Untracked files +@chapter Untracked files + +Untracked files are shown in the @emph{Untracked changes} section. + +You can instruct Git to ignore them by typing @kbd{i}. This will add +the filename to the @code{.gitignore} file. Typing @kbd{C-u i} will +ask you for the name of the file to ignore. This is useful to ignore +whole directories, for example. The @kbd{I} command is similar to +@kbd{i} but will add the file to @code{.git/info/exclude} instead. + +To delete a untracked file forever, use @kbd{k}. + @node Staging and Committing @chapter Staging and Committing @@ -137,10 +152,6 @@ changes} section shows the changes that will be included in the next commit, while the @emph{Unstaged changes} section shows the changes that will be left out. -Untracked files are shown as @emph{New} in the @emph{Changes} or -@emph{Unstaged changes} section. You can instruct Git to ignore them -by typing @kbd{i}. - You can discard uncommitted changes by moving point into a hunk and typing @kbd{k}.