2

Is there a git extension or setting that list files with corresponding numbers next to the names when typing 'status'? In effort to not have to type the file path each time one is interested in manipulating the git state.

For example currently when typing 'git status':

modified:   app-src/angular/common/environment.provider.js
modified:   app-src/other/URLS.js
modified:   app-src/react/common/environment.js
modified:   app-src/react/complex_builder/BrowseComponent.js
modified:   app-src/react/redux/store.js

is a typical view of what is displayed which then using the file path changes can be made. I'm curious if there is anyway to display like such:

modified:  (1) app-src/angular/common/environment.provider.js
modified:  (2) app-src/other/URLS.js
modified:  (3) app-src/react/common/environment.js
modified:  (4) app-src/react/complex_builder/BrowseComponent.js
modified:  (5) app-src/react/redux/store.js

and the corresponding numerals can be used for manipulation.

Wanted to put this out there in case I've missed the solution to this... otherwise I'll actually look at what is going on under the git hood and make this myself I guess. Thanks!

rsmets
  • 789
  • 1
  • 13
  • 23
  • There is no. Perhaps you'd like to use some kind of GUI tools for git: gitk, git gui, git-cola, etc… – phd May 03 '18 at 22:06
  • @phd thanks for the suggestions but looking for CLI functionality. Although for a git GUI I like to use Sourcetree. – rsmets May 03 '18 at 22:20

4 Answers4

3

Made a small bash script. It may help. You can modify it to your own needs.

#!/bin/bash
# Script Name: git-bash.sh
#
# Author: Krishnadas P.C<pckrishnadas88@gmail.com>
# Date : 05-05-2018
#
# Description: A simple script to manipulate git files.
# TODO add more options and add Error Handlers. 

#decalre color variables
red=`tput setaf 1`
green=`tput setaf 2`
reset=`tput sgr0`

#print the current git branch
echo "On Branch - $(git branch)"
#Get only staged files
gitstaged=($(git diff --name-only --cached))

#Get changes not staged for commit
gitnotstaged=($(git diff --name-only))

#Get only untracked files
gituntracked=($(git ls-files --others --exclude-standard))

if [ $# -ge 3 ];
then
   if [ $2 == "st" ];
   then
       git $1 ${gitstaged[$3]}
   elif [ $2 == "nt" ]; 
   then  
    git $1 ${gitnotstaged[$3]}
   elif [ $2 == "ut" ]; 
   then  
    git $1 ${gituntracked[$3]}
   else
     echo "Invalid input provied."
   fi     
fi
#Get the new status after the command has been executed.
gitstaged=($(git diff --name-only --cached))

#Get changes not staged for commit
gitnotstaged=($(git diff --name-only))

#Get only untracked files
gituntracked=($(git ls-files --others --exclude-standard))
#print the staged files.
for i in ${!gitstaged[@]}; do
   if [ $i -eq 0 ]; then 
    echo "Changes to be committed:" 
   fi
   echo "${green}st$i - ${gitstaged[$i]}${reset}"
done
#print the changes not staged files.
for i in ${!gitnotstaged[@]}; do
   if [ $i -eq 0 ]; then 
    echo "Changes not staged for commit:" 
   fi
   echo "${red}nt$i - ${gitnotstaged[$i]}${reset}"
done
#print the untracked files.
for i in ${!gituntracked[@]}; do
   if [ $i -eq 0 ]; then 
    echo "Untracked files:" 
   fi
  echo "${red}ut$i - ${gituntracked[$i]}${reset}"
done

: 'Example how to:
#$ ./git-bash.sh 
Untracked files
ut0 - git-bash.sh
ut1 - git-status.txt
ut2 - test
$./git-bash.sh add ut 0
Staged files
st0 - git-bash.sh
st1 - git-status.txt
Untracked files
ut0 - test
ut stands for untracked files.
nt stands for notstaged tracked files.
st stands for staged files.
'

ut stands for untracked files.
nt stands for notstaged tracked files.
st stands for staged files.

Sample output

$ ./git-bash.sh 
On Branch - * master
Untracked files:
ut0 - git-bash.sh
ut1 - git-status.txt
ut2 - test

$ ./git-bash.sh add ut 2
On Branch - * master
Changes to be committed:
st0 - test
Untracked files:
ut0 - git-bash.sh
ut1 - git-status.txt

UPDATED VERSION 11-05-2018

#!/bin/bash
# Script Name: igit.sh
#
# Author: Krishnadas P.C<pckrishnadas88@gmail.com>
# Date : 05-05-2018
#
# Description: A simple script to manipulate git files.
# TODO add more options and add Error Handlers. 
# Need help for adding error handlers.

#declare color variables
red=`tput setaf 1`
green=`tput setaf 2`
reset=`tput sgr0`

#prints the help message if $1 is help
#TODO Nicely format the help and add more example.
if [ "$1" == "help" ];
  then
  less << EndOfMessage
IGIT - Indexed git for adding/removing git files using file list index not by it\'s name

Author: Krishnadas P.C<pckrishnadas88@gmail.com>
Repo: https://github.com/pckrishnadas88/indexed-git

ut stands for untracked files.
nt stands for notstaged tracked files.
st stands for staged files.

After a command has been executed it shows the updated status.

1. To Simply view the status execute the command without any args.
  $ ./igit.sh 
  Untracked files
  ut0 - igit.sh
  ut1 - git-status.txt
  ut2 - test
2. To add an untracked file(ut) run like this where 0 is the index from the previous command.
  $./igit.sh add ut 0
  Staged files
  st0 - igit.sh
  st1 - git-status.txt
  Untracked files
  ut0 - test
3. To add multiple files using comma seperated method
   $./igit.sh add ut 1,2,3  #Here 1, 2, 3 are the index of the files.
4. To add multiple files using a range like 1..10 adds 10 files.
  $./igit.sh add ut 1..10
EndOfMessage
exit
fi
#end of help text section.

#print the current git branch
echo "On Branch - $(git branch)"
#Get only staged files
gitstaged=($(git diff --name-only --cached))

#Get changes not staged for commit
gitnotstaged=($(git diff --name-only))

#Get only untracked files
gituntracked=($(git ls-files --others --exclude-standard))

#print the clean message if all three arrays are empty.
cleanmsg="nothing to commit, working directory clean"
if [ ${#gitstaged[@]} == 0 ] && [ ${#gitnotstaged[@]} == 0 ] && [ ${#gituntracked[@]} == 0 ];
  then
  echo $cleanmsg
fi

if [ $# -ge 3 ];
then
   #process comma seperated multiple files ie git add 1,2,3
   fileindex=""
   multifile="false"
   #check whether string contains a ,
   if [[ $3 == *[,]* ]]
   then
     #set multi file to true
     multifile="true"
     a=(`echo $3 | sed 's/,/\n/g'`)
     for i in ${!a[@]}; do # Loop and build the multi file string.
      if [ $2 == "st" ]; #staged files section.
         then
         fileindex+="${gitstaged[$i]} " #use the appropriate git array.
      elif [ $2 == "nt" ]; 
         then
         fileindex+="${gitstaged[$i]} "
      elif [ $2 == "ut" ]; 
         then
         fileindex+="${gituntracked[$i]} "
      else 
         echo "Invalid input provided"
         exit
      fi
     done
   fi
   #multi file adding with lower upper limits ie 1..10
   if [[ $3 == *[..]* ]]
   then
     #set multi file to true
     multifile="true"
     IFS='.. ' read -r -a multiarray <<< "$3"
     lowerlimit=multiarray[0]
     upperlimit=multiarray[2]
     for ((a=$lowerlimit; a <= $upperlimit ; a++))
      do
         if [ $2 == "st" ]; #staged files section.
         then
         fileindex+="${gitstaged[$a]} " #use the appropriate git array.
         elif [ $2 == "nt" ]; 
            then
            fileindex+="${gitstaged[$a]} "
         elif [ $2 == "ut" ]; 
            then
            fileindex+="${gituntracked[$a]} "
         else 
            echo "Invalid input provided"
            exit
         fi
      done
      echo $fileindex
      echo ${gituntracked}
      #exit
      #exit
   fi
   #staged files section.
   if [ $2 == "st" ]; 
   then
      if [ $multifile == "true" ];
      then
        git $1 $fileindex
      else 
       git $1 ${gitstaged[$3]}
      fi
   elif [ $2 == "nt" ]; # not staged but tracked files section.
   then 
      if [ $multifile == "true" ];
      then
        git $1 $fileindex
      else 
       git $1 ${gitnotstaged[$3]}
      fi 
   elif [ $2 == "ut" ]; 
   then 
      if [ $multifile == "true" ];
      then
        git $1 $fileindex
      else 
       git $1 ${gituntracked[$3]}
      fi 
   else
     echo "Invalid input provied."
   fi     
fi
#Get the new status after the command has been executed.
gitstaged=($(git diff --name-only --cached))

#Get changes not staged for commit
gitnotstaged=($(git diff --name-only))

#Get only untracked files
gituntracked=($(git ls-files --others --exclude-standard))
#print the staged files.
for i in ${!gitstaged[@]}; do
   if [ $i -eq 0 ]; then 
       echo "Changes to be committed:" 
   fi
    echo "${green}st$i - ${gitstaged[$i]}${reset}"
done
#print the changes not staged files.
for i in ${!gitnotstaged[@]}; do
   if [ $i -eq 0 ]; then 
    echo "Changes not staged for commit:" 
   fi
   echo "${red}nt$i - ${gitnotstaged[$i]}${reset}"
done
#print the untracked files.
for i in ${!gituntracked[@]}; do
   if [ $i -eq 0 ]; then 
    echo "Untracked files:" 
   fi
  echo "${red}ut$i - ${gituntracked[$i]}${reset}"
done

New features, Option to add multiple files with it's index.

  1. To add multiple files using comma separated method

    $./igit.sh add ut 1,2,3 #Here 1, 2, 3 are the index of the files.

  2. To add multiple files using a range like 1..10 adds 10 files.

    $./igit.sh add ut 1..10

  3. To view the help text simply pass the help as the arguement

    $./igit.sh help

    Link to the Github Repo

Krishnadas PC
  • 5,981
  • 2
  • 53
  • 54
2

Many git commands git add, git reset, git commit, git clean` have an interactive mode and/or a patch mode. There you can select files in a similar way as you suggested.

Short example

> git status
modified some-changed-file
> git add -i
           staged     unstaged path
  1:    unchanged        +1/-0 some-changed-file

*** Commands ***
  1: status   2: update   3: revert   4: add untracked
  5: patch    6: diff     7: quit     8: help
What now> u

           staged     unstaged path
  1:    unchanged        +1/-0 Documentation/git-diff.txt
Update>> 1
Update>> <just enter>
What now> q
Bye.

Now the file is staged.


On the other hand there are tools like Git Commander which provide nice UIs in the terminal.

A.H.
  • 63,967
  • 15
  • 92
  • 126
  • 1
    thanks! Not exactly the solution but just grabbed Git Commander and seems like it's a bit easier than the native file path solution. Will give it a go for a while but first glance certainly addresses the pain point! – rsmets May 04 '18 at 18:28
  • 1
    @discodude: Hahaha, I wrote the answer on a phone and autocorrection kicked in badly. I meant "plain git commands" not "Git Commander". But that's OK also. I will edit the answer. – A.H. May 05 '18 at 07:28
  • for the record git commander has actually been a super useful cli tool. I love native git but the ease of use of "gc" as I have it aliased is pretty cool. – rsmets Nov 26 '18 at 22:09
1

Not that I know of.

You could wrap git status --porcelain in order to parse its output, and add those numbers.

But then Git would know nothing about them, and wouldn't be able to reference them in other commands.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Thought about something similar but the caveat is definitely Git being oblivious. Thanks for the suggestion thought. – rsmets May 04 '18 at 18:25
1

It's not exactly a CLI, but it can be used in a terminal window if you want...

You can install emacs, and then install the magit emacs package inside emacs. Then start magit by issuing the command magit-status to emacs. If you are not currently in a repository directory (note: emacs inherits its working directory from the shell you start it from), it will ask you to enter the repository directory to use.

Magit lists all the changed files, and then you can move your cursor down to the file you are interested in, using ordinary arrow keys or emacs shortcut keys, and the press Tab to expand the diff inline, or Enter to open the file for editing in emacs. You can also use other keys like s to stage (add) the file to the git index ready for committing, and then c to commit all the staged changes.

Robin Green
  • 32,079
  • 16
  • 104
  • 187
  • thanks for the suggestion. I've never heard of the magit emacs package. Interesting solution/work around. It seems like the Git Commander A.H. suggested does this in a much more intuitive fashion. – rsmets May 04 '18 at 18:27