Reputation: 51
I probably abuse git and use it in ways it was never designed to be used. I am a sole developer of team size one where I develop across multiple machines. For example, I code on machine A, and need to test (and recompile) the code on machine B and machine C. I do rapid developing (e.g., a commit every minute, and then go across to machine B/C to test).
Consequently, many of my commits have meaning messages, specifically I do this very often:
machine A
git add -u
git commit -m "work"
git push
machine B/C
git pull
make
./run_tests
Oh no! it doesn't work... go back to machine A and make another commit 1 minute later.
Consequently, as you can imagine, my git --log history has a lot of worthless comments that only contain "work". Is there a way to automatically combine all git commits that have the same message, specifically, all sequential commits with -m "work" will be combined into one big commit -m "big work".
Thanks.
To be explicit, my comment history (going back 2 years) is something like this:
work
work
work
work
OMG THIS actually works.
work
work
work
OMG we solved a huge problem... we should call this v1.0
work
work
work
I want to autosquash all the "work" messages to become something like:
work
OMG THIS actually works.
work
OMG we solved a huge problem... we should call this v1.0
work
etc...
Side, As to why I abuse git like this, basically I am using it as ctrl-s feature... I also develop across 20 machines and need an efficient manner to share code after a change every minute or so. NFS is not an option as I also work on machines offline / hard firewalled / etc...
Upvotes: 5
Views: 3401
Reputation: 971
The workflow you're describing is very similar to what is described in the git-rebase Interactive Mode man page:
Rebasing interactively means that you have a chance to edit the commits which are rebased. You can reorder the commits, and you can remove them (weeding out bad or otherwise unwanted patches).
[...]
If you want to fold two or more commits into one, replace the command "pick" for the second and subsequent commits with "squash" or "fixup". If the commits had different authors, the folded commit will be attributed to the author of the first commit. The suggested commit message for the folded commit is the concatenation of the commit messages of the first commit and of those with the "squash" command, but omits the commit messages of commits with the "fixup" command.
Applying git-rebase example to your case, you'll have to do something like
$ git rebase --interactive HEAD~13 # to fix last 12 commits
An editor will be fired up with all the commits in your current branch:
pick deadaaa work
pick deadbbb work
pick deadccc work
pick deadddd work
pick deadeee OMG THIS actually works.
pick deadfff work
pick dead000 work
...
What you have to do is to change "pick" into "fixup" on commits you want to adjoin into upper commit:
pick deadaaa work
fixup deadbbb work
fixup deadccc work
fixup deadddd work
pick deadeee OMG THIS actually works.
pick deadfff work
fixup dead000 work
...
After this clean-up the safest thing to do is re-cloneing this repository from the rest of your machines. Since messing up with commits (like git rebase does) on a shared repository is a perfect recipe for disaster. Especially if you'll try to automate this process.
EDIT: When you have all the copies of the repository under control, this should not be a problem. Just make sure all the copies are in sync before you tinker the master branch. And after you finish update all the copies with force push/pulls to be in sync again. If something goes wrong "Recovering from Upstream Rebase" git-rebase man section should help.
Upvotes: 3
Reputation: 26555
You are not abusing git. This is an absolute fine scenario for git.
I would recommend setting up your work repository at A
to contain (beside the probably existing remote origin
) two more remotes remote_B
and remote_C
. (And on host B
and C
you set up a corresponding bare repository.)
This allows you to work at A
and simply push your commit to the host by something using git push remote_B
. - You can automate this a little bit further by adding a small hook at the remote repositories to automatically build your project and run the test.
This way you just push and see the result at once, without the need to ever leaving A
.
Now for your actual question: I would first strongly recommend to use a bit more meaningful commit messages. - You usually work on some given topic, or try to fix some special problem. - give yourself a hint what the commit is about.
Once you got your test working use git rebase -i
. As long as you did not change your upstream, (which is probably pointing to origin
and you push there only after finishing work,) git rebase -i
shows exactly those commits you did not push yet and allows you to combine, reorder, and rename them as you like. - At this point is is very helpful to have some meaningful commit messages to be able to combine them in a meaningful way.
As a final step when you are happy with the result push you work to origin
and everything is fine. :)
Upvotes: 3