git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[FYI PATCH v2] Added a git search and replace command

From
Sverre Rabbelier <srabbelier@gmail.com>
Date
Jul 23, 2008, 19:55 UTC
Message-ID
<1216842920-25600-1-git-send-email-srabbelier@gmail.com>

A simple script that uses 'git ls-files' and a bash for loop to search and replace (using sed) all the specified files. There is a config option for the pathspec. This allows the user to set 'sar.pathspec' and then specify only the sed on the commandline. ---

  Not meant for inclusion, just a simple script I wrote up
  when I wanted to change a function name in my repository
  but didn't want to figure out which magic argument to
  find does what I want. Another advantage of using git
  ls-files is that it will prevent that any unrevertable
  changes will be made (since the script checks if the tree
  is dirty or not). I'm sure there's plenty of room for
  improvement here, it's probably not portable at all
  either, so comments are welcome :).
  
  Changes since v2, the use of xargs was taken out and
  replaced by a bash for loop. Also I added a config value
  because I'm too lazy to type the pathspec each time.
  
  Interdiff below:
  
  diff --git a/git-sar.sh b/git-sar.sh
  index db6317b..e64b9bd 100755
  --- a/git-sar.sh
  +++ b/git-sar.sh
  @@ -1,24 +1,26 @@
   #!/bin/bash
   
  -do_sed () {
  -  sed "$2" $3 > $3.replaced
  -  mv $3.replaced $3
  -}
  -
   do_git_find() {
     # Sanity check
     if is_dirty_tree
     then
       echo "Refusing to work on a dirty tree"
  +    exit 1
     fi
   
     files=`git ls-files "$1"`
  +
  +  # See if there were any matching files
     if test -z "$files"
     then
       echo "Your pathspec did not match any files."
       exit 1
     fi
  -  echo "$files" | xargs -n 1 git-sar --replace $2
  +
  +  # Change them in-place
  +  for file in $files; do
  +    sed -i "$2" "$file";
  +  done
   }
   
   is_dirty_tree () {
  @@ -33,27 +35,28 @@ do_show_usage() {
   
   do_main() {
     # Verify argument size
  -  if test "$#" -le 1 -o "$#" -ge 4
  +  if test "$#" -ge 3
     then
       do_show_usage
     fi
   
  -  # Two argument form
  -  if test "$#" -eq 2
  +  if test "$#" -eq 1
     then
  -    do_git_find "$@"
  -  fi
  +    glob=`git config --get sar.pathspec`
   
  -  # Three argument form, we're calling ourselves through sed
  -  if test "$#" -eq 3
  -  then
  -    # Double check if the user typoed or if we are indeed meta-calling
  -    if test "$1" != "--replace"
  +    if test -z "$glob"
       then
  +      echo "No sar.pathspec set"
         do_show_usage
       fi
   
  -    do_sed "$@"
  +    do_git_find "$glob" "$1"
  +  fi
  +
  +  # Two argument form
  +  if test "$#" -eq 2
  +  then
  +    do_git_find "$@"
     fi
   }
 .gitignore |    1 +
 Makefile   |    1 +
 git-sar.sh |   64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 66 insertions(+), 0 deletions(-)
 create mode 100755 git-sar.sh
diff --git a/.gitignore b/.gitignore
index a213e8e..451cb93 100644
--- a/.gitignore
+++ b/.gitignore
@@ -108,6 +108,7 @@ git-rev-list
 git-rev-parse
 git-revert
 git-rm
+git-sar
 git-send-email
 git-send-pack
 git-sh-setup
diff --git a/Makefile b/Makefile
index b01cf1c..979e9ea 100644
--- a/Makefile
+++ b/Makefile
@@ -252,6 +252,7 @@ SCRIPT_SH += git-sh-setup.sh
 SCRIPT_SH += git-stash.sh
 SCRIPT_SH += git-submodule.sh
 SCRIPT_SH += git-web--browse.sh
+SCRIPT_SH += git-sar.sh
 
 SCRIPT_PERL += git-add--interactive.perl
 SCRIPT_PERL += git-archimport.perl
diff --git a/git-sar.sh b/git-sar.sh
new file mode 100755
index 0000000..e64b9bd
--- /dev/null
+++ b/git-sar.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+
+do_git_find() {
+  # Sanity check
+  if is_dirty_tree
+  then
+    echo "Refusing to work on a dirty tree"
+    exit 1
+  fi
+
+  files=`git ls-files "$1"`
+
+  # See if there were any matching files
+  if test -z "$files"
+  then
+    echo "Your pathspec did not match any files."
+    exit 1
+  fi
+
+  # Change them in-place
+  for file in $files; do
+    sed -i "$2" "$file";
+  done
+}
+
+is_dirty_tree () {
+  `git diff --quiet`
+  test $? -ne 0
+}
+
+do_show_usage() {
+  echo "usage: git-sar pathspec sed"
+  exit 128
+}
+
+do_main() {
+  # Verify argument size
+  if test "$#" -ge 3
+  then
+    do_show_usage
+  fi
+
+  if test "$#" -eq 1
+  then
+    glob=`git config --get sar.pathspec`
+
+    if test -z "$glob"
+    then
+      echo "No sar.pathspec set"
+      do_show_usage
+    fi
+
+    do_git_find "$glob" "$1"
+  fi
+
+  # Two argument form
+  if test "$#" -eq 2
+  then
+    do_git_find "$@"
+  fi
+}
+
+do_main "$@"
+
-- 
1.6.0.rc0.15.gc85d5
Message 1 of 1 in “Added a git search and replace command”
  1. Added a git search and replace commandSverre Rabbelier, Jul 23, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.