Bandit 31 → 32: the file git kept pretending to add
Five git levels in a row, and this is the one that flips direction. Every level before it handed me a repository to dig through; this one wants something put into it. Create a file, commit it, push it — and the push came back telling me there was nothing to send.
the goal
There is a git repository at
ssh://bandit31-git@localhost/home/bandit31-git/repovia the port2220. The password for the userbandit31-gitis the same as for the userbandit31. From your local machine (not the OverTheWire machine!), clone the repository and find the password for the next level. This needs git installed locally on your machine.
Word for word the last four again. The actual task isn’t on the level page at
all — it’s in the repo, in README.md:
File name: key.txt
Content: 'May I come in?'
Branch: master
the approach
Clone from my own machine, since localhost in that URL still means whichever
machine runs the command — the 27 → 28 lesson, still applying five levels later:
git clone ssh://bandit31-git@bandit.labs.overthewire.org:2220/home/bandit31-git/repo
Then the file, spelled exactly the way the README asks for it:
echo 'May I come in?' > key.txt
git add key.txt
git commit
the identity error that hid the real one
git refused the commit — not over the file, over me. It wanted a name and an email before it would write anything:
git config --global user.name bandit31
git config --global user.email bandit31@overthewire.org
Real failure, real fix, and also the reason the next thing took a while: I’d just watched a commit get refused and then repaired, so when the push did nothing I had no reason to look at the file. The first problem made the second one look like it had already been solved.
git push origin master
Everything up-to-date
Which is a strange thing to be told about a file that is definitely not up there.
nothing to commit
git status
nothing to commit, working tree clean
Now two commands agreeing there was nothing to do, about a file I could see in
ls. “Working tree clean” does not mean “your file is committed” — it means
nothing git is tracking differs from HEAD, and a file git has been told to
ignore is not something it’s tracking.
The trap is one line, and it shipped with the repo:
.gitignore
*.txt
key.txt matches. So git add key.txt put nothing in the index, git commit
had nothing to commit, and git push had nothing to push. Four commands doing
exactly what they were told, and every one of them honest — the mistake happened
before the first of them ran.
force it past
git add -f key.txt
git commit -m "Add key.txt"
git push origin master
-f is the whole fix: it tells add to stage the file even though an ignore
rule covers it. With the file actually inside a commit the push had something to
carry, and the password came back with it — redacted here as <password>.
the takeaway
git add -f forces a file past .gitignore. That’s the brick — a one-flag
answer to a problem that gives you no error to work from.
What made it cost that much is the shape of the failure. Nothing errored.
add, commit, push and status were all correct and all useless, because an
ignore rule had removed the file from the conversation before any of them
started. An empty index gives you four commands’ worth of true, unhelpful
answers. A dead end that announces itself is easy; this one agrees with you.
Two smaller ones:
“Everything up-to-date” is a statement about commits, not about intent. It means the remote branch has everything the local branch has. It says nothing whatsoever about the file sitting in the directory you’re standing in.
A repo you cloned arrives with its rules attached. .gitignore is a file in
the repository, written by whoever built it — and here it was written to swallow
*.txt on a level whose entire task is to commit key.txt. Reading it costs one
command, and it’s the one worth running before you trust anything downstream.