14

Just curious if Git has something like Subversions Changelist feature, its something that I find quite handy working with on the fly, I know I could run something like:

cat 'changelistfileimade' | xargs git update

but am curious if there's a built in method too?

BuZZ-dEE
  • 6,075
  • 12
  • 66
  • 96
ehime
  • 8,025
  • 14
  • 51
  • 110
  • There's no such thing as `git update`. The equivalent of `svn update` is `git fetch`+`git merge`/`git rebase` (but non-destructive, compared to `svn update` which could trash your working copy's state) – knittl May 15 '12 at 18:59
  • 1
    short: for every svn *changelist* you create a (local) git *branch*. Changelists are only a workaround for not having local branches in svn. – JonnyJD Dec 28 '12 at 11:11
  • Correction: changelists are also a way of maintaining local modifications without overwriting files the repository. I keep several changelists for things in configuration files like my local database connections strings, paths to development resources, resource URIs, and experimental changes to a branch. Those are things that have specific values when deployed, but are different when we use them in a development environment. – Suncat2000 Feb 14 '18 at 15:39

2 Answers2

16

I googled around a bit more for this and I think I've found a replacement for the TortoiseSVN ignore-on-commit changelist use case I mention in my comment above. The command in question is git update-index --assume-unchanged <path/name>. Git help has this to say about it:

--[no-]assume-unchanged

When these flags are specified, the object names recorded for the paths are not updated. Instead, these options set and unset the "assume unchanged" bit for the paths. When the "assume unchanged" bit is on, Git stops checking the working tree files for possible modifications, so you need to manually unset the bit to tell Git when you change the working tree file. This is sometimes helpful when working with a big project on a filesystem that has very slow lstat(2) system call (e.g. cifs).

This option can be also used as a coarse file-level mechanism to ignore uncommitted changes in tracked files (akin to what .gitignore does for untracked files). Git will fail (gracefully) in case it needs to modify this file in the index e.g. when merging in a commit; thus, in case the assumed-untracked file is changed upstream, you will need to handle the situation manually.

I found an explanation of the option on Nick Quaranto's GitReady blog, which includes the following:

Obviously there’s quite a few caveats that come into play with this. If you git add the file directly, it will be added to the index. Merging a commit with this flag on will cause the merge to fail gracefully so you can handle it manually.

But that's only half the battle for me. The next step is knowing what you've ignored (and hopefully remembering why). That was provided by this handy comment by Abe Voelker on an aptly named question. Simply edit your .gitconfig file with the snippet

[alias]
    ignored = !git ls-files -v | grep "^[[:lower:]]"

Don't add the [alias] bit if it already exists in your file. And now git ignored will tell you something like this:

h configs/environment/local.php
h configs/logging/log4php.xml

You can take this a step further with aliases for ignore and unignore with the following lines:

    ignore = update-index --assume-unchanged
    unignore = update-index --no-assume-unchanged
Community
  • 1
  • 1
Patrick M
  • 10,547
  • 9
  • 68
  • 101
  • Unfortunately this only works for new files. If you make a change to a file that is already added to git, then assume-unchanged has no effect. There is another flag called skip-worktree, however, if you use it, then you can no longer use checkout to switch to different branches. For me this is a show stopper. Bottom line, i must use zip/unzip to save/restore all my changes that I do not want committed. Its a real pain. See http://stackoverflow.com/questions/43770228/git-how-to-switch-branches-without-committing-your-changes – John Henckel May 08 '17 at 19:00
14

I have never used SVN changelists myself, but if I understand correctly, it allows you to group files into changelists and later separately commit those changelists. (Right?)

I don't think you really need such a feature with Git. You can already separately stage (git add) each file or parts of it (git add -p) independently and commit those. You can create branches for each of your changelist, and later merge/rebase those branches. Or you can create several commits and later re-order them with interactive rebase (git rebase -i).

Instead of svn diff --changelist something, you will simply use git show changelistbranch.

You don't have to push those local/temporary branches. Nobody needs to see them, until you consider them ready to be released into the wild.

You can even namespace your "changelist branches": git branch changelist/name_of_your_changelist, you will then have all changelists grouped by their prefix.

Am I missing something?

knittl
  • 246,190
  • 53
  • 318
  • 364
  • 1
    @knitti I think there as recent as 1.5 if I'm correct. They're nice in the fact that you can assign product parts to separate lists, and update without too much hassle when the time comes to push. – ehime May 15 '12 at 18:52
  • @ehime: then I have not used SVN since 1.5 ;) – knittl May 15 '12 at 18:54
  • 6
    Working with svn changelists to prepare a commit is like having multiple staging areas in git (which do not exist). – BHF Oct 18 '13 at 06:49
  • 1
    @BHF: Git still allows you to work on the level of changes and not on a file level. I find this far superior. With the power of rebase and local commits you don't need multiple staging areas. – knittl Oct 18 '13 at 07:55
  • 4
    I would like to have this feature. The main thing I used it for in SVN was holding onto changes locally without worry of anyone else being bothered by them or having them unexpectedly appear in production. This was a very common occurrence with configuration files. An SVN changelist would essentially cache your changes if you changed branches. `git stash` provides some of that functionality, but it's not automatic. But in Git, I have to be careful with staging changes; no convenience of `git add .`. TortoiseSVN even came with ignore-on-commit changelist, which worked very well for this use. – Patrick M Jun 24 '14 at 20:28
  • 2
    Fortunately IntelliJ IDEA does have this feature built-in also for git. If git doesn't support it then it seems IDEA itself keeps track of which files are in which changelist. – herman Sep 07 '15 at 08:56