Pergunta

I changed some files in my repo, but don't want them to be pushed public or create any temporary branch to store them. I just want to save these changes in somewhere. So which command is better:

git stash save "save message" 

or

git commit -am "save message"

?

If I use git commit, is it true that all of my local commits will be pushed publicly by one git push command? What if I just want to push one specific commit among them?

Foi útil?

Solução

When pushing, you always push one specific commit (usually the commit at the tip of your currently checked out branch). However, as the commit's hash partly consists of the commits it bases on (its parent commits), you have to push all parent commits also. And by pushing the parent commits you also have to push their parent commits and so on. So, you can only push the whole history of a specific commit.

If you create a commit just to store something but not for pushing, you need to make sure that you never push that commit, nor any commits that base on that commit. To do that, after you have done your work that bases on the temporary commit, you need to squash the temporary commit into the new commit that you create to push it.

In other words, yes it is possible to use a commit for temporary, private storage. However, it is much easier to use the stash feature. In fact, the feature is made for this very use case.

Outras dicas

Personally I prefer just going straight to private (local) branches, but stashes work. Be aware of two things about stashes:

  • They are their own commits. Except for the label, there's no fundamental difference between the "stash" commit and a commit tied to a branch or tag label. (A tag label has the form refs/tags/tag-foo; a branch has the form refs/tags/branch-foo; and the—single—labeled stash commit is labeled refs/stash. Of course, branch labels also have the "automatically moves as you add commits" feature, but if you never add more commits there, they never move, so they work just as well to save a single commit.)
  • The stash "stack"1 is implemented using reflogs. Reflogs can expire—by default most do (after 30 or 90 days), and those in refs/stash do not, but you can change this with configuration entries—so stacked stash commits can also "expire" (at the same time the reflog entry expires). (More precisely, they "become collectable", but this distinction is not helpful if they're gone. :-) )

The intent with stashes is to save something short-term. If you've ever come back to a repo late and find a bunch of stashes, all named "WIP on branch", it is no fun trying to figure them out.

The other features/bugs :-) stash provide are:

  • git stash branch lets you change your mind after the fact and turn a stash into a branch. So, if "short term" turns out to be an issue (you were going to fix it this afternoon but now it's been pushed off for at least a month) you can just turn the stash into a branch after all.
  • git stash apply [--index] will do its best to "re-make" the applied change in the current branch. With --index it will try to restore both the staged and unstaged changes independently. (There are cases where this is impossible, though.)
  • git stash pop automatically discards the stash reference for you. Unfortunately it does this even if you meant to use git stash pop --index and left out the --index part. It's easy to lose some of your state (staged vs unstaged) if you use pop. If you use apply, and later drop once you're sure you have everything back the way you wanted, you can avoid this problem.

Note that git stash branch implies --index: the newly created branch will have staged-and-unstaged changes restored to the way they were when you did the git stash. (The branch will branch off from the commit you were on when you did the git stash, too.) Commit the changes (git add-ing more if desired, or as two separate commits, or whatever) and proceed as if you'd made a private branch in the first place.


1The expire-able part of the stack consists of all stashes other than stash@{0}, in git stash list output.

I do things a little bit differently. Stashes to me are more for quick saves, not daily work since they aren't (easily) granular in what you can actually stash. (i.e. If I have 20 changed files and I want to create two stashes of ten each, it's not easy to do.)

That's why I want my daily changes committed to an actual, albeit temporary branch only for my personal usage so I can include notes and such of my work as I go. Daily check-ins, experiments, etc. Basically things I don't want pushed to the final repo.

When I'm in a state where I'm ready to commit back to the main repo, I use the 'soft reset' command on the commit I originally branched from. This puts all of my temp-branch-committed changes back as current changes on that original commit without any of my daily working history.

I then create a new branch for these "new" changes and I can either commit them all at once, or I can break it apart into several commits if it makes sense (i.e. one for the back-end stuff, another for the front-end stuff, another for resources, etc.)

When I'm done, I'm left with a nice, new, clean branch with a history that makes sense to other devs, free of my daily notes, and ready to merge and push back into the main repo. Then I can delete my temp branches and move on to the next task.

So to recap...

  1. Create a working branch
  2. Make as many commits/sub-branches as you need to get your job done
  3. When you're ready to merge back without keeping that history, git-reset back to the original commit where you branched. All your changes are now local changes.
  4. Re-commit and merge as you see fit

Another benefit is I can actually push the temporary branches to the remote repo so I can work from multiple locations which you can't do with a stash. Just remember when you're done, clean things back up off of the server to keep repo browsing clean. (Some may argue that technically the commits are still there, just detached, which is true, but branches are light-weight in GIT, and in a way, it becomes another safety net for not losing work as you can get back a detached commit if really necessary.)

I suggest you to use stashing tool for it. That is why is it here. You can stash your chnges and later add them to your code. There are lots more functionality which you can use with git stash. Here is the link http://git-scm.com/book/en/Git-Tools-Stashing

I would suggest you to once go through the documentation of git here. Also read about the tool. After this you'll become the master of git for sure.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top