83

I found that the shelve/unshelve commands in TFS are very handy and very simple to use. What's the equivalent in Git ?

here's the scenario in TFS :

  • I made changes in the trunk
  • I shelve : the change set is saved on the server (with a label) and I get the source back before the changes
  • I work in the trunk
  • Someone can unshelve : get the change set in his workspace

I know that there's a command call cherry-pick but i"m not sure of the workflow and if it fits the need.

MatthieuGD
  • 4,552
  • 2
  • 30
  • 29

3 Answers3

87

What you describe is similar to git stash, except since with git you have your own repository (not just a single one on a server), only you can get that change set back.

The general idea is:

# do some stuff
vim foo/bar.c
# stash away your changes
git stash

# do some other things...

# retrieve your changes
git stash pop

If you wanted someone else to have access to this changeset, you'd want to instead commit it to a working branch:

# make yourself a branch
git checkout -b temp-featureA
# commit to it
git add foo/bar.c; git commit

# now you push this branch (or they could just fetch straight from you)
git push origin temp-featureA


# Now, in someone else's repo:
# Fetch updates
git fetch origin
# Make a branch tracking the remote branch
git branch temp-featureA origin/temp-featureA

# Either check it out:
git checkout temp-featureA
# or cherry-pick it, to apply the changes somewhere else:
git cherry-pick temp-featureA
# or, if it's multiple commits, rebase it!
git rebase --onto my-branch start-of-featureA temp-featureA
Cascabel
  • 479,068
  • 72
  • 370
  • 318
  • Any idea what to do if I dont want to commit these changes in the shelveset? We have connectionstrings we change to hit different environments, but we dont want change these on master, only for local debugging, if we have them in a branch they will be commited when we push if we merge them into our branch – Mech0z Nov 28 '16 at 15:04
  • Is there a way to stash while preserving the local changes? May be stash followed by stash apply? – Psddp May 07 '18 at 18:43
  • Yes, stash then stash apply would essentially do that. But I'm a little confused why you'd want to. Generally if you're stashing it's because you *want* the changes to temporarily disappear, and you'll put them back somewhere else. If you're going to keep them around and keep working, you might be better off just making a commit. You can then cherry-pick that commit elsewhere instead of applying a stash, and you can always squash it away afterwards if you want to clean up. – Cascabel May 07 '18 at 18:47
  • 5
    Actually this really isn't the same as a TFS Shelveset. If I'm working on a local git branch...at the end of the day I want to say...with all the warts and compile errors....put this work on the server for safe keeping. So, if my hard drive crashes, I don't lose everything. However, I do not want to push my work up to the remote branch yet because it's incomplete. My local branch is tracking the remote branch. Cascabel lists 8 separate git commands to orchestrate this...in TFS...it's one command...Shelve. – Bayrat May 23 '18 at 15:30
31

What you want to do is accomplished with plain old branching in git.

From a nice StackOverflow answer by JaredPar:

Shelving is a way of saving all of the changes on your box without checking in. The changes are persisted on the server.

This is analogous to committing to a branch and pushing it to a server in git.

How to do it:

Let's say you're working on the "master" branch and you decide to implement feature X. You get a good start on it, but then your boss tells you that feature Y needs implemented as soon as possible. Phil in the next cube over volunteers to finish feature X while you do feature Y. Here's what you do:

Make a new branch and switch to it:

$ git checkout -b feature-x

Commit your changes:

$ git add filethatyouchanged.cc
$ git commit -m 'partial implementation of feature X'

Push it to a server that Phil can see:

$ git push origin feature-x

Go back to the master branch (which has not changed):

$ git checkout master

You might also want to proactively create a new branch for feature Y:

$ git checkout -b feature-y

Phil can now pull down your feature X work and pick up where you left off:

phil$ git fetch origin
phil$ git checkout -t origin/feature-x
Community
  • 1
  • 1
Neall
  • 26,428
  • 5
  • 49
  • 48
  • 2
    although not as cheap as in git, it is actually stored in the repo, and if the repo is distributed, that means that you can have your shelve served to any computer from the repo, without it becoming a commit. (TFS2010) This is very handy if there's some kind of policy like CI or Gated Check-In (mandatory server side build at every check-in) – Onno Apr 09 '14 at 22:56
5

git stash is a bit similar, except it is limited to your working tree.

In a DVCS, to achieve that kind of workflow, you need to:

  • commit your current changes in a new branch
  • checkout the original branch where you can go on, with none of the changes you had introduced (but committed in the new branch)
  • push that new branch to a bare repo
  • allow another developer to pull that new branch and merge it to his current branch.

Another way would be to let the other developer fetch your branch (where you have committed that special set of changes), and cherry-pick it, but that is not recommended, for cherry-picked commits are hard to track.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Thank for your answer, I marked Jefromi's answer because it gives me an example but yours was also helpful. – MatthieuGD Jun 18 '10 at 15:22