views:

917

answers:

11

Is it possible to create a non-visible branch in git or mercurial I can use as backup? Eg at the end of the day I have unfinished work (may even be left with syntax errors) but I want it to be backed up in the repository online, without annoying others about the mess that's left.

A: 

That's not really the purpose of SCM. Maybe something like rsync to upload it to a server would be a better idea?

Loïc Wolff
+1  A: 

With mercurial, when you merge, you merge all your changesets, including those commits "just for saving unfinished work". If you don't want them to end in the tree don't commit them.

For git, as far as I know, the default behavior is the same and editing the commit history to remove them is annoying as well.

So, as suggested, rsync looks like a better option.

Bluebird75
This is why development in a personal branch is common / popular, and it's the majority of what makes a distributed VCS great. Before you commit, you can change to the production branch, rebase or merge how you wish it to be seen, and then push only those changes you wanted. Rsync is a poor choice to handle the question.
Autocracy
+2  A: 

You could accomplish this if you had two remote clones of the repository:

stable
unstable

Push to unstable (your backup) until you've finished a feature. Once the feature is finished, push the branch to stable. Lather, rinse, repeat.

bendin
+1  A: 

The latest version of TortoiseHg allows you to shelve your changes.

In a nutshell:

Shelved changes are physically removed from the working directory until you unshelve them. This means you can build your project and run tests on it while the shelved changes are gone. This is safer than selecting changes at build time since you can test whether the change being committed is valid.

Shelving changes is also useful for removing partially completed work to make sure it doesn't interfere with the debugging of other changes you are making.

Lieven
+3  A: 

Git allows you to mirror your repository very easily;

Let's say you have a remote repo called 'backup', e.g.,

git remote add --mirror backup server.com:/home/koen/backup_repo.git

Then backing up is as easy as

git push backup

A few notes:

  • if you didn't use --mirror when adding the remote repo, then use --mirror in your push command
  • the remote repo should be a "bare" repository (since you're pushing into it)
  • checkout the git push and git remote help regarding --mirror
Pat Notz
+7  A: 

By default git clone and git fetch/merge only download refs in refs/heads/*. So anything you push to somewhere else won't be downloaded by others (unless they explicitly ask for them or do something like git clone --mirror). So, for instance, you can do:

git push origin HEAD:refs/koen/my_work

to push your current commit. Using that complete refspec, you can also pull it from another checkout:

git pull origin refs/koen/my_work

To automate pushing your HEAD, you could do something like

[remote "origin"]
    url = [email protected]:pieter/gitx.git
    push = :
        push = refs/heads/*:refs/koen/*

that will push all your branches to the remote without bothering anyone else. It'll also keep the default push behaviour that you're used to. If you don't want that, remove the push = : line.

Pieter
A: 

I think this depends more on how your repository is made visible and what permissions you have. In principle, you just need a temp branch to use as a "save area" that you push to the hub repo--- I think you already know that. Is there a general way to flag a branch as "not visible"? I don't believe so, although you could experiment with pushing your local head ref to oddly-named refs on the other end, e.g.:

git push central refs/heads/master:refs/remotes/tmp/master

This would try to create "refs/remotes/tmp/master", which is a valid refname but not what is usually considered a branch. For instance, gitweb will show such a ref if it appears in the history of one of the branches under refs/heads/ but will not show a list of all the remote refs.

Alternatively, just bite the bullet and push to a visible branch called "probably-broken-use-at-your-peril" ;)

araqnid
A: 

On our mercurial project we use multiple branches. The default branch is like a "trunk". Every time I start a feature I branch out and develop there. I commit, push, go to another place, pull, commit, push. The default branch stays untouch and everybody else doesn't whatch my branch. When I'm done, I merge the branch into default.

artemb
A: 

With Git, you usually have private repository, non-bare which means that it does have working directory. You create new commits there, apply patches, pull/fetch from other repositories. This repository is hosted on your private machine.

Then you have public repository, bare which means that it doesn't have working repository. You push to this public repository (which can be for example hosted on one of git hosting sites like repo.or.cz, GitHub or Gitorious) from your private repository when your works stabilizes. You can push only subset of branches from your private development repository to this public publishing repository (for example Git maintainer, Junio C Hamano, does not push feature branches into public git.git repositoris). This public repository is where other people fetch from.

This separation has the advantage that you can fix commits (for example using "git commit --amend") which are not pushed into public repository, and otherwise rewrite parts of history which is present only in private development repository.

Jakub Narębski
+1  A: 

While this isn't private (anyone in your company can get to them, just not by default, so it's not annoying), this is what I do:

In ~/.gitconfig

[alias]
  backup = !git push -v origin +refs/heads/*:refs/wip/`git config --get user.email`/*

So, that way, you can at any time on your local repo run:

git backup

All of your local branches (under refs/heads anyway) will be pushed to the "origin" repo under the refs/wip/your_email/ namespace, unconditionally (same as push -f).

Once you're ready to push to origin/master, if you've been using this to back up your work in progress, the push will be really fast, since most (all) of the SHA1 objects will be already at the origin server.

Note that from time to time you will want to purge backups, so that the origin repo can garbage collect stuff. See:

git ls-remote origin refs/wip/`git config --get user.email`/*

That will give you a list of the branches you've pushed to backups, so you can know/automate what to clean.

Jordi Bunster
+3  A: 

Anything you push to the shared repository will be universally seen / available. Your two simple options are:

  • Create your own second repository at a separate location and push your development branch to there at the end of the every day. You would not push your development branch to the stable one everybody else uses.

  • The second option that doesn't involve having a whole second repository, but will take more work on your part at the end of the day, is to export patches for your work. The standard git email patch method will result in all your commits being maintained in case you want to backup that pattern as well. Compress the patch and upload it somewhere.

Autocracy