git-bash-editing
Skill1 starsChanged 13 days agoMITView on GitHub
Use when writing a script or a file body from Git Bash (read this first; never put file contents in a heredoc, use the Write and Edit tools), editing source with sed, perl, python or heredocs, looping over sqlcmd output, or overwriting generated files that also hold hand edits. Trigger words - backslashes mangled, escape became a newline, unexpected EOF, CRLF pattern matches nothing, path rewritten, working directory reset, junction for a scratch copy.
In this repository30 other files it gives its agents.
- angular-crud-gotchasSkill
- aws-lightsail-container-deploySkill
- bannerlord-decompileSkill
- codegen-t4-templatesSkill
- csharpSkill
- delphi-code-smellsSkill
- delphi-firedacSkill
- delphiSkill
- delphi-types-and-unitsSkill
- difftasticSkill
- dockerSkill
- efcore-aspnet-reviewSkill
- github-issue-creatorSkill
- microsoft-docsSkill
- minimal-comments-and-docsSkill
- msbuildSkill
- mssqlSkill
- mstest-assertionsSkill
- mysqlSkill
- nginx-config-testingSkill
- odata-generated-gridsSkill
- postgresSkill
- powershellSkill
- react-crud-gotchasSkill
- sanitize-for-open-sourceSkill
- self-contained-deploymentSkill
- skill-writerSkill
- ui-conventionsSkill
- verify-in-running-appSkill
- winui3Skill
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 3 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 38
Never sed 's/\\d/.../' to fix a backslash: it matches every letter d.
- Very specific: line 39
After a scripted edit of a string literal, grep -n the line.
- Very specific: line 42
Verify regex edits by printing repr() of the text around a match before deciding the pattern is wrong.
- Distinctive: line 58
Before overwriting files that may hold hand edits, confirm git status --short is clean.
- Distinctive: line 63
Read this skill before scripting edits.
- Distinctive: line 64
If a task is much bigger than its label ("small", "cheap"), say so and ask for the reduced or full version before starting.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Editing files from Git Bash on Windows
The rule
Do not carry a large file body or script in a Bash heredoc. Use Bash to run things. A small or medium heredoc (a short script or edit, up to about 40 lines) is fine when it holds no apostrophe, backslash, backtick or $ that must reach the file; larger bodies fail ("unexpected EOF", mangled escapes) and go through Write.
| Need | Do this |
| Create or replace a file, or write a Python/JS script | Write tool (scripts to the scratchpad), then run python C:/.../file.py |
| Change one line or one short block | Edit tool, typing escapes exactly as they must appear in the file |
| The same replacement in many files | a script file made with Write: raw strings, assert text.count(old) == 1, read and write with newline='' |
A short command with no ', \, backtick or $ | Bash is fine |
A heredoc longer than about 40 lines, or one whose text needs an apostrophe, backslash, backtick or $ to survive, belongs in a file made with Write (the Edit tool for a short block). After every scripted edit, grep -n or sed -n the changed line before building; a script that "ran" proves nothing.
Shell rejections and rewrites
unexpected EOF while looking for matching 'rejects the whole command and nothing in it ran (checkls -la/git statusbefore assuming a partial result). Cause: an apostrophe or quote inside a large heredoc, even with<<'EOF'. Fix: Write the file, then run it.rm -f $TEMP/*.py(a variable in a wildcard path) is refused and the whole command line, including the commands before it, does not run. Clean up in its own call with literal paths, or leave scratch files.- A Windows path passed to a Windows program is rewritten.
sqlcmd -i /c/x/y.sqlfails with "Error occurred while opening ... C:" and the script silently did not run. A forward-slash path with a drive letter (-i C:/Users/me/y.sql) fails too:sqlcmdreadsC:plus switches,/Usersbecomes-U, and the message is the misleading "The -E and the -U/-P options are mutually exclusive". A relative path or a backslash path works (see themssqlskill). Use the PowerShell tool with a backslash path, or"$(cygpath -w /c/x/y.sql)". An argument starting with/is also turned into a path: setMSYS_NO_PATHCONV=1. After DDL, query the catalog to confirm it took effect. - Python run from Git Bash cannot see
/c/...either (FileNotFoundError): passC:/...paths topythonand to any Windows program. A multi-line edit script of more than a few lines goes in a file made with Write, even when it looks harmless (an apostrophe or a backslash inside a 90-line heredoc rejects the whole command). - Python run from Git Bash cannot see
/tmp. Put scratch files in the session scratchpad with aC:/...path. A file that a Bash command already wrote to/tmpis reached with"$(cygpath -w /tmp/x.sql)"as an argument topython; a script that reads/tmp/xitself fails withFileNotFoundErrorbefore it changes anything (seen when appending a snippet to a SQL file). - The working directory resets between Bash calls: use absolute paths or
cdin the same command. Environment variables do not persist either:exportthem in the command that starts the server.
Escapes: what reaches the file
- Python/JS strings turn escapes into real characters.
'\n','\r\n','\d','sql\functions'(a form feed),'8.0\bin'(a backspace) written into a file come out as a real line break, a lone letter or a control character. Symptoms: C#CS1010 Newline in constant,CS1009 Unrecognized escape sequence, a regex(\d{4})arriving as(d{4}), a doc line printingsqlunctions. Python'sSyntaxWarning: invalid escape sequenceis the signal that the file content is now wrong.- Fixes in order: the Edit tool; a raw string
r'...';chr(92)for a backslash; in C# tests a verbatim string@"...\d{4}...". - In C# a test string
"\'x\'"is just'x': the backslash is an escape, not a character. A test to feed text that holds a backslash and a quote (MySQL'sCHECK_CLAUSEshows_cp850\'open\') passed for the wrong reason until it was written@"\'open\'". Write the input as a verbatim string, and see the test fail once with the old behaviour before trusting it. - A Python replace written in a Bash heredoc (
t.replace("_cp850\\'", ...)) and asedwith\\'both changed nothing or damaged the file (a stray quote was appended); after a backslash-and-quote edit,od -cthe line, then redo it with a script made with Write that builds the backslash withchr(92). - Through the Bash tool a doubled
\\nin a Python heredoc arrives as\nand is then read as a newline. Another reason not to use heredocs. re.sub(pattern, "text with \n", s)interprets backslashes in the replacement: pass a function (lambda m: text).- Never
sed 's/\\d/.../'to fix a backslash: it matches every letterd. - After a scripted edit of a string literal,
grep -nthe line; a quote followed by a line break means repair it with Edit. For a corrupted path,grep -c $'\x0c'and$'\x08'find form feeds and backspaces. - A JS template literal turns
\`into a backtick and\\into one backslash: write the content as it should appear, with no second layer.
- Fixes in order: the Edit tool; a raw string
perl -e,perl -pi -e,sed s///lose backslashes ('\\'became'\',\.lost its dot). In perl, write a single quote as\x27and a literal$as\$; better, avoid perl and use Edit.sed -ireplacement text containing|or&needs escaping: beyond one literal word, use Edit.- Verify regex edits by printing
repr()of the text around a match before deciding the pattern is wrong.
CRLF, BOM and line endings
- Most trees here are CRLF (
core.autocrlf=true). A multi-lineperl -0pipattern with\nmatches nothing and reports no error. Write\r?\n, emit\r\n, and check withgit diff. The Edit tool also needs an exact match: on CRLF files edit single lines. - In a Python script:
nl = '\r\n' if '\r\n' in s else '\n'; read and write withnewline=''; keep a UTF-8 BOM (EF BB BF,utf-8-sig) if the file had one;assert s.count(old) == 1before.replace. A file that mixes LF and CRLF: edit as bytes and match the line ending explicitly. - Compare generated (LF) output with a CRLF original:
git diff -w --ignore-cr-at-eol --ignore-space-at-eol -U0 <files> | tr -d '\r' | grep '^[-+]'. The "LF will be replaced by CRLF" warnings are harmless. - The Edit and Write tools refuse a file not read in this conversation, or one changed since (by an IDE, a formatter, a sed pass): Read it again, then edit.
sqlcmd and loops
sqlcmdoutput ends each line with\r.for t in $(sqlcmd ... -h -1 -W -Q ...)then fails on every name but the last, and agrep errorfilter hides it. Pipe throughtr -d '\r', and when a loop produces fewer results than items, rerun one iteration unfiltered.
Scratch copies and overwriting
- Copy a Node project without reinstalling:
tar --exclude=node_modules --exclude=.git --exclude=dist --exclude=.angular -cf - . | (cd DEST && tar xf -), then linknode_moduleswith a junction made in PowerShell:New-Item -ItemType Junction -Path DEST\node_modules -Target SRC\node_modules(cmd //c mklink /Jfails from Git Bash with "syntax incorrect"). - Before overwriting files that may hold hand edits, confirm
git status --shortis clean.git checkout -- fileundoes a generate but also discards earlier hand edits in the same file: generate and hand-fix different files in different passes, or diff first. - Program Files folders (such as the SQL Server Backup folder) may be unreadable and undeletable from the session: do not work around it with
xp_cmdshellor bulk-delete procedures; tell the user the path.
Process
- Read this skill before scripting edits; the rules were known and still skipped once.
- If a task is much bigger than its label ("small", "cheap"), say so and ask for the reduced or full version before starting.
- Real checks (an
npm installand build per version, a database copy, a live API run) take minutes each: run them in one background job with a log file and aDONEmarker, and read the log at the end. - A fix found by a live run also needs a unit test, or the next edit loses it.
Traps seen in sessions
The saved tools (edit_text.py and the others in C:\Github\tools) are listed in the global CLAUDE.md; check them before writing a scratch script.
- A Windows Python does not understand Git Bash paths (
/c/Github/xbecomesC:\c\Github\xand "file not found"). PassC:/Github/x; the saved tools convert/c/...themselves. - Run a long job with
run_logged.pyandrun_in_background: true, not( cmd > log; echo DONE ) &. The subshell form returns at once, so the completion notice arrives for the wrong thing; the harness already notifies when a background command exits. Use a new log name per run: after a rerun, notices (and Monitor events) of the earlier run still arrive and look like results. A foregroundsleepand a chain of short sleeps are blocked; do not poll. - Do not make a "just in case" backup copy and delete it. The delete of a stray file in the drive root was refused by the safety check and nothing in the command ran, including the edit that followed it. Use
git diff/git checkoutfor undo, and put scratch files in the scratchpad folder.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

