{"thread":{"id":"14638","subject":"[FYI PATCH v2] Added a git search and replace command","startedAt":"2008-07-23T19:55:20Z","lastAt":"2008-07-23T19:55:20Z","messageCount":1,"participants":["Sverre Rabbelier"],"isPatch":true,"patchVersion":2,"patchTotal":null},"messages":[{"id":"84597","messageId":"1216842920-25600-1-git-send-email-srabbelier@gmail.com","threadId":"14638","inReplyTo":null,"subject":"[FYI PATCH v2] Added a git search and replace command","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2008-07-23T19:55:20Z","receivedAt":"2008-07-23T19:55:20Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"A simple script that uses 'git ls-files' and a bash for\nloop to search and replace (using sed) all the specified\nfiles. There is a config option for the pathspec. This\nallows the user to set 'sar.pathspec' and then specify only\nthe sed on the commandline.\n---\n\n  Not meant for inclusion, just a simple script I wrote up\n  when I wanted to change a function name in my repository\n  but didn't want to figure out which magic argument to\n  find does what I want. Another advantage of using git\n  ls-files is that it will prevent that any unrevertable\n  changes will be made (since the script checks if the tree\n  is dirty or not). I'm sure there's plenty of room for\n  improvement here, it's probably not portable at all\n  either, so comments are welcome :).\n  \n  Changes since v2, the use of xargs was taken out and\n  replaced by a bash for loop. Also I added a config value\n  because I'm too lazy to type the pathspec each time.\n  \n  Interdiff below:\n  \n  diff --git a/git-sar.sh b/git-sar.sh\n  index db6317b..e64b9bd 100755\n  --- a/git-sar.sh\n  +++ b/git-sar.sh\n  @@ -1,24 +1,26 @@\n   #!/bin/bash\n   \n  -do_sed () {\n  -  sed \"$2\" $3 > $3.replaced\n  -  mv $3.replaced $3\n  -}\n  -\n   do_git_find() {\n     # Sanity check\n     if is_dirty_tree\n     then\n       echo \"Refusing to work on a dirty tree\"\n  +    exit 1\n     fi\n   \n     files=`git ls-files \"$1\"`\n  +\n  +  # See if there were any matching files\n     if test -z \"$files\"\n     then\n       echo \"Your pathspec did not match any files.\"\n       exit 1\n     fi\n  -  echo \"$files\" | xargs -n 1 git-sar --replace $2\n  +\n  +  # Change them in-place\n  +  for file in $files; do\n  +    sed -i \"$2\" \"$file\";\n  +  done\n   }\n   \n   is_dirty_tree () {\n  @@ -33,27 +35,28 @@ do_show_usage() {\n   \n   do_main() {\n     # Verify argument size\n  -  if test \"$#\" -le 1 -o \"$#\" -ge 4\n  +  if test \"$#\" -ge 3\n     then\n       do_show_usage\n     fi\n   \n  -  # Two argument form\n  -  if test \"$#\" -eq 2\n  +  if test \"$#\" -eq 1\n     then\n  -    do_git_find \"$@\"\n  -  fi\n  +    glob=`git config --get sar.pathspec`\n   \n  -  # Three argument form, we're calling ourselves through sed\n  -  if test \"$#\" -eq 3\n  -  then\n  -    # Double check if the user typoed or if we are indeed meta-calling\n  -    if test \"$1\" != \"--replace\"\n  +    if test -z \"$glob\"\n       then\n  +      echo \"No sar.pathspec set\"\n         do_show_usage\n       fi\n   \n  -    do_sed \"$@\"\n  +    do_git_find \"$glob\" \"$1\"\n  +  fi\n  +\n  +  # Two argument form\n  +  if test \"$#\" -eq 2\n  +  then\n  +    do_git_find \"$@\"\n     fi\n   }\n\n .gitignore |    1 +\n Makefile   |    1 +\n git-sar.sh |   64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 66 insertions(+), 0 deletions(-)\n create mode 100755 git-sar.sh\n\ndiff --git a/.gitignore b/.gitignore\nindex a213e8e..451cb93 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -108,6 +108,7 @@ git-rev-list\n git-rev-parse\n git-revert\n git-rm\n+git-sar\n git-send-email\n git-send-pack\n git-sh-setup\ndiff --git a/Makefile b/Makefile\nindex b01cf1c..979e9ea 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -252,6 +252,7 @@ SCRIPT_SH += git-sh-setup.sh\n SCRIPT_SH += git-stash.sh\n SCRIPT_SH += git-submodule.sh\n SCRIPT_SH += git-web--browse.sh\n+SCRIPT_SH += git-sar.sh\n \n SCRIPT_PERL += git-add--interactive.perl\n SCRIPT_PERL += git-archimport.perl\ndiff --git a/git-sar.sh b/git-sar.sh\nnew file mode 100755\nindex 0000000..e64b9bd\n--- /dev/null\n+++ b/git-sar.sh\n@@ -0,0 +1,64 @@\n+#!/bin/bash\n+\n+do_git_find() {\n+  # Sanity check\n+  if is_dirty_tree\n+  then\n+    echo \"Refusing to work on a dirty tree\"\n+    exit 1\n+  fi\n+\n+  files=`git ls-files \"$1\"`\n+\n+  # See if there were any matching files\n+  if test -z \"$files\"\n+  then\n+    echo \"Your pathspec did not match any files.\"\n+    exit 1\n+  fi\n+\n+  # Change them in-place\n+  for file in $files; do\n+    sed -i \"$2\" \"$file\";\n+  done\n+}\n+\n+is_dirty_tree () {\n+  `git diff --quiet`\n+  test $? -ne 0\n+}\n+\n+do_show_usage() {\n+  echo \"usage: git-sar pathspec sed\"\n+  exit 128\n+}\n+\n+do_main() {\n+  # Verify argument size\n+  if test \"$#\" -ge 3\n+  then\n+    do_show_usage\n+  fi\n+\n+  if test \"$#\" -eq 1\n+  then\n+    glob=`git config --get sar.pathspec`\n+\n+    if test -z \"$glob\"\n+    then\n+      echo \"No sar.pathspec set\"\n+      do_show_usage\n+    fi\n+\n+    do_git_find \"$glob\" \"$1\"\n+  fi\n+\n+  # Two argument form\n+  if test \"$#\" -eq 2\n+  then\n+    do_git_find \"$@\"\n+  fi\n+}\n+\n+do_main \"$@\"\n+\n-- \n1.6.0.rc0.15.gc85d5\n"}]}