Git (or other open-source) hints/tips?

I’m not sure of the best place to put this, but I wanted to share ideas and see what git (or other source control packages) commands people use a lot. Obviously there are places for specific questions, like Stackoverflow, but I was curious if anyone writing text adventures used particular ones.

I suppose first we all probably are familiar with:

git clone
git fetch
git pull
git push

Then, to create commits and so forth,

git add
git commit
git pull
git push

Or to see what changed
git diff
git diff --word-diff # to see only words that changed, handy if we just tweak “credits” or something
git diff --U0 # to see contextless changes

If we did a bunch of work, or fixed a bunch of miscellaneous bugs, and want to divide it up into different commits…

git add --patch story.ni

If we want to get rid of that last commit …

git reset HEAD~1

Anyway, these were the ones that helped me get rid of a lot of busy work, and I’m curious what other people have found that maybe gave, or gives, them a big boost.

1 Like

I never understood git merge because I never want to put other people’s code into my code without me going through full analysis of the whole thing. Practically speaking, I consider merging to be an attack vector. I wonder why so many people highlight merging as desirable feature of git. Can you explain it?

The main git commands I use a lot that I see missing in your list are git branch, git checkout, git log, git stash, git merge and git cherry-pick. Those are mostly useful if you are working on separate features in parallel branches.
Another very useful git command is git bisect if you are trying to find the commit that caused a bug.

3 Likes

Merging is not just about other people’s code, but your own as well. If you create a separate branch to work on something and then want to integrate that work into the master/main branch, you do a merge. And if you work across multiple machines, then implicit merges happen every time you do git pull.

As for other people’s code, yes it’s probably unwise to just blindly apply someone’s changes. But once you reviewed them and are happy with the work you will ultimately need to git merge to apply them.

3 Likes

I also think git merge can save time in some cases. On another project I was invited to, it took so long to write up issues for small grammar tweaks and then have the project manager go through them individually. It was just easier for me to create a pull request and have them merge it.

And I’ve seen a (sadly still WIP) IF project in-person where co-authors have sent each other pull requests to merge. One did the coding, one did the creative stuff, and it worked well.

I’ve only used merge for REALLY big features. For Ailihphilia, I had a lot of work to do to revamp the hints. But I also had small bugs along the way. So it was nice to have the “hints” branch.

It seems like this is generally good policy for stuff like IFComp where you can provide fixes, but you don’t want to make any big ones. So you keep the necessary fixes in “main” and find other branches to merge post-comp.

1 Like

For an IFComp entry I would go the other way, making a branch for hot fixes to the submission and keeping the master branch open for further development - I’m sure some of the fixes will be just hacks that I would never directly merge in master.

1 Like

I think it could work either way. I’ve found most of my IFComp fixes are the “gee, how’d I overlook that, that’s low risk high benefit” variety. Perhaps it’d be good to have 100%-sure fixes in the main branch, comp hot fixes in another, and long-term fixes in a third.

1 Like

I find that

git status

… is also useful in case

git diff

… overwhelms you with all the changes…

4 Likes

When I track down problems in Inform6 code, I frequently put in lots of debugging prints and the like. Then I make lots of tiny commits marking when I find out something new. This is necessary because there still is not a debugger available. I don’t want to clutter up the main history with all this, so I put the changes into a branch. When I find the solution, which is often one or two lines of code, I distill the changes and apply just them.

I also find that a history viewer like gitk is extremely useful in visualizing changes, no matter the language.

2 Likes

I work as a software developer, so I probably use all the git commands. But here are a few of my git aliases, which I didn’t write myself originally but which come in handy:

[alias]
        find-merge = "!sh -c 'commit=$0 && branch=${1:-HEAD} && (git rev-list $commit..$branch --ancestry-path | cat -n; git rev-list $commit..$branch --first-parent | cat -n) | sort -k2 -s | uniq -f1 -d | sort -n | tail -1 | cut -f2'"
        show-merge = "!sh -c 'merge=$(git find-merge $0 $1) && [ -n \"$merge\" ] && git show $merge'"
        st = status -sb
        unstage = reset HEAD --
        last = log -1 HEAD
        amend = commit --amend --no-edit
        alias = !git config --list | grep 'alias\\.' | sed 's/alias\\.\\([^=]*\\)=\\(.*\\)/\\1\\\t => \\2/' | sort

Merging might not be terribly useful if you’re just developing a game linearly from start to finish (even if you meander a bit on the way), but if you ever want to refactor huge chunks of your game/program, it’s very nice to be able to make a separate branch to mess around in while you keep adding other stuff to the main branch.

3 Likes

Hey, wow, thanks everyone for the tips so far. I’ve seen a lot of new stuff I’m going to use, as well as some stuff I’d seen before and wish I’d remembered. (It probably didn’t seem useful at the time as a rookie. It does now.)

Ooh! Advice I wish I’d known earlier!

Before I really used branching, I had big refactoring projects that were mostly replacing. I usually got them done, but sometimes I put them off because of other things, and other times I did them and put off other things I wanted to do.

So many shortcuts in git just seem like shortcuts until you realize how much energy and focus they save.

Incidentally, for those who wish to use the command line instead of @tobiasvl 's modification

git config --global alias.unstage “reset HEAD --”
git config --global alias.decommit “reset HEAD~1”

(This is on Windows. You may want single quotes on *nix.)

Agreed … git status -uno was also handy for me so I could ignore untracked files.

(Note: I didn’t actually look up the .gitconfig file now. On Windows it was in c:\users\andrew. Most probably already know this, but for those who don’t, you can make a short batch file to open it or just use git config --global -e.

Well, merging is fundamental to working on teams with multiple people. If you have multiple people always working off your latest master they’ll be tripping all over each other and it’ll be a huge mess; there’s no way to exclusively lock a file in git and locking files is insufficient in containing changes anyways. I’m a little confused by why you think it’s an attack vector, because the command doesn’t preclude you from reviewing their changes before accepting them.

Anyways, a couple of commands I use heavily that I haven’t seen are:

git show - shows you the last commit; git show <commit> shows you the target commit.

git reflog - this lets you see the reference log, which lists all of the git actions you’ve taken; if you do something silly on your local branch and want to undo it, like deleting or merging the wrong thing, reflog is your friend. You can find the desired commit and check it out and not lose any work.

git rebase -i HEAD~<n> - this drops you into interactive rebase mode, which lets you move specific commits up and down, edit their names, break of combine them, etc. If you’re new at using rebase mode you might want to branch off into a temp branch because it can be annoying to recover. Really helpful if you’re prepping a branch to merge into master and your commit history is an unhelpful sea of lol it no work attemping fix #7 fml messages. Probably unnecessary if you’re working alone.

1 Like