I'm using Git to manage a small repository of small shell scripts. There's a lot of them and none justify a repository of their own, so I clump them together in a single repository.
To keep things clean, I have a few long running branches - one for scripts I'm still working on, another for scripts I've generally completed but still testing, and another for verified, trustworthy scripts. Naturally, I move them between the branches occasionaly.
I'm currently transferring the scripts between branches using git checkout {branch} {filename}
, but this only imports the file as it currently is, leaving its' history in the old branch.
It's not terribly important, but out of curiositry - is there a way to move a single file between branches with its' history?
Thanks!
In Git, files don't have history. Instead, commits are history. The history in a Git repository is found by:
It's this stepping-back, from commit to earlier commit, that is the act of exploring history. Hence the commits are the history.
Now, each commit contains files: in fact, each commit has a full copy of every file, saved in a read-only format, compressed and—since most commits mostly copy some previous commit's files unchanged—de-duplicated. So given some set of commits that are history, we can have Git filter away some or even most of the history, showing us only those commits that Git thinks we'll find particularly interesting. This is how git log -- path
and git log --follow -- filename
work. They look at some subset of the actual history—some set of commits—and simply lie to you, using carefully selected, programmatically-controllable lies that give you the useful information.
You must keep in mind that these are lies that you control with options like --simplify-by-decoration
or --full-history
. Otherwise you'll be fooled by the lies. The actual history is the commits and Git is filtering some away.
Making a new commit leaves all the existing commits unchanged. It must because no part of any commit can ever be changed, not even by Git itself. (This is how Git manages to do the "distributed" part of being a Distributed Version Control System.)