Posts tagged with “”

Git Tip: Ignore Changes to Tracked Files

Every once in a while, I find myself working on a project that forces me to modify key files—often config files—in order to get it running locally. In those cases, the last thing I want to do, for a number of reasons, is to commit those changes. That’s hard to do, though, since I regularly use git add . and/or git ci -a to commit everything I’ve changed. Make enough changes in enough files that you don’t want to commit and these changes begin to cause as many problems as they solve.

As is so often the case, it seems, Git comes to the rescue with its update-index command. Reading the documentation, it’s not really intended for this purpose, but its effectiveness as a “coarse file-level mechanism to ignore uncommitted changes in tracked files” is recognized. To apply it, simply make a change to a committed file, say, database.yml and execute git status. Git should report the modified file. Since we don’t want to commit, we don’t want to see this listed as a modified file until the end of time and we can’t ignore it (because it’s already being tracked), we need to tell Git to assume the file is not changed.

git update-index --assume-unchanged path/to/database.yml

I’ve been using this command since I learned of it a few weeks ago and it works perfectly for this use case. Inevitably, though, a question will arise:

What files have I marked this way?

Since those files will no longer appear in the modified list, can’t be easily found in a .gitignore file or exposed by removing a .gitignore file, there will eventually be a need to know this. Maybe you’re trying to get another instance running or maybe you’re just the curious sort and you’ve forgotten. Like many things in Git-land, the functionality exists, but is far from obvious. I asked on StackOverflow and Andrew Aylett provided the answer I was looking for.

If you ever find yourself needing to know, this command will display the files that have been marked as —assumed-unchanged.

git ls-files -v | grep -e "^[hsmrck]"

Thinking in Subversion

I just spent more time than I should have needed to spend learning that svn revert is so not the same thing as git revert.

I had modified a page in my working copy while trying to track down and understand the nature of an error. Once I figured out what I needed, I wanted to get my working copy of that file back to where I started. Having been a Subversion user for so long, I immediately tried to revert those changes. Wrong. Then I tried git reset only to find that while it works on entire repositories, it doesn’t work on individual file paths. At a loss, I turned to Twitter and, once again, Twitter delivered.

Thanks to Ben Kutil and Brad Greenlee, I learned that git checkout is what I needed. That never even occurred to me and, honestly, I doubt I would have tried it even if it had occurred to me. I’d have assumed it would throw an error. In the git paradigm, of course, it makes perfect sense that no error is thrown, but I’m still ascending that learning curve. I’m still thinking in Subversion.

Ignore Git's Suspicious Patch Lines

Those who follow me on Twitter have recently been forced to endure a steady stream of rants directed at Git, the DCVS I’ve been trying out while working on the new theme for this site (one really is coming). I’ve only tweeted a fraction of my frustration, but this tweet sums it up nicely:

What the fuck is up with git and its need for precisely zero trailing whitespace?! Suspicious patch lines my ass.

It seems that Git is a finicky little bastard and it pays obscenely close attention to whitespace. If there is a line, any line, with whitespace at the end of it Git decides that something must be fishy. I mean, it’s whitespace. Horror. Everyone knows whitespace is the very spawn of Satan, right? Er, no. Nonetheless, if there’s any trailing whitespace to be found in content that’s being committed, Git balks:

*
* You have some suspicious patch lines:
*

The message then proceeds to itemize its suspicions for my viewing pleasure. Tonight I’d finally had enough. I can’t figure out how to make Git force the commit or at least stop it from worrying its pretty little head over a little empty space, so I took drastic measures:

$ sudo chmod a-x /path/to/my/repository/.git/hooks/pre-commit

That’ll teach it to mess with me.

Help, Twitter Style

Last night I had my first truly useful experience with Twitter. Until then, Twitter had really just been my little digital diary, I suppose. I’ve had some productive (read: enlightening) trade-offs with smart people that I follow like Peter Bell, Sammy Larbi and Bill Mill, but mostly it’s just me talking to myself.

Last night, though, I was doing my usual digital musing and got a surprise. I was grumbling about some trouble I was having getting the git version control system installed on my Mac via MacPorts. I was slowly working through it, but I couldn’t help bitching about it just a little. What shocked me was that several people, including a couple that don’t know me or follow me, stepped up to help or at least offer encouragement. I thought that was pretty cool.

I don’t know how they found my tweets, but I appreciate them jumping in to help.

Installing MacPorts with tcsh

This evening I’m beginning my foray into the world of Git in order to see what all of the fuss is about. On Mac, the first step was to install MacPorts. That’s also where I ran into my first problem. I don’t know yet whether this is a really nasty omen, but I thought it might be worth documenting the problem and the solution.

I started by downloading the MacPorts package installer; I seldom mess with source code installs without a compelling reason to do so. Once it was downloaded, I ran the installer. This is pretty basic stuff, so when the installer told me it completed successfully, I assumed that it, you know, completed successfully and I tried to install git:

$ sudo port install git-core sudo: port: command not found

Oops. I’m a man; I hate reading instructions, but now I had to. So I visited the MacPorts installation instructions and they assured me that the installer would take care of everything for me:

This procedure will place a fully-functional and default MacPorts installation on your host system, ready for usage. If needed your shell configuration files will be adapted by the installer to include the necessary settings to run MacPorts and the programs it installs, but you may need to open a new shell for these changes to take effect.

I opened a new shell, but it still didn’t work. Evidently, all of this automation only happens if the default shell is bash. My default shell on every Unix (or derivative) box that I spend a significant amount of time logged into is tcsh. I have this set specifically since Mac, like most other Unix variants I’ve used, defaults to bash when a new user is created.

Fortunately, MacPorts documents the shell changes, but even the documentation is bash-centric. It’s an easy translation, though. I added the following lines to my .tcshrc file:

# # Macports environment variables # set MANPATH = `manpath` setenv PATH /opt/local/bin:/opt/local/sbin:$PATH setenv MANPATH /opt/local/share/man:$MANPATH

Once I saved those changes, closed and reloaded my .tcshrc file (e.g. $ source ~/.tcshrc) the system was able to run the port executable.