Refactoring a project to get stable and trunk branches using bazaar - bazaar

I'm relatively new to VCS and especially Bazaar so I started my project without using it, using a structure like this
+project_root
+scripts
+bin # Binaries for easy testing
+dev # Sources root
+package_folder
+package_folder
...
But I've been told that VCS are the best thing since set theory, so I've tried to put it under Bazaar, using that I've done a
cd scripts/dev
bzr init
bzr add
bzr commit -m "Initial import"
Now (how cool is that) I just bzr commit -m "spam" whenever I feel like it and bzr push when I don't trust my HDD.
But now that I have some stable and distributable code, I have set up a project at launchpad and I'd like to have some trunk branch where I could make unstable commits just to backup and a stable branch for the users to use.
That is to say I'd just have to spawn some command and it will update stable at the current state of trunk when I have a stable version I want to distribute, bundling all intermediate revisions into one.
How can I do this, if possible without refactoring my folder structure, and what should be my project structure on launchpad according to the usuals conventions?

The question is more about Launchpad than bzr.
You can set up your trunk as default branch on launchpad, or you can set up your stable branch as default branch on Launchpad. Open the series page for your project:
https://launchpad.net/PROJECT/+series
Click on trunk series. You should be able to select the branch you want to be associated with trunk series. https://launchpad.net/PROJECT/trunk/+edit Let's select your trunk here.
Now you should return to series page and create a new series let's call it "stable".
https://launchpad.net/PROJECT/+addseries
For stable series you should select another branch, let's select your stable branch.
So now, when you or your users will use short URL like lp:PROJECT then it will access your trunk branch. If another short URL will be used: lp:PROJECT/stable then it will access your stable branch.
lp:PROJECT/XXX will access the branch associated with XXX series.

Related

IntelliJ: How to create a local Java project copy for backup?

I'm new to JavaFX 8 and the IntelliJ IDE. I have a JavaFX8 project that works but not as I would like. I'd like to try another approach but the substantial changes may not work. I don't want to loose code I have working.
To save code I have working, I've been creating a new project and then locally copying all the folders(.idea, out, src) and files except .iml, of the working project into the appropriate folders in the new project with the newly generated .iml.
This always seems to work but is it proper procedure?
I'm not on a team of developers and have yet to learn Git/GitHub.
Please advise. Thanks.
Maybe you should learn how to use a Version Control System like Git, then you can create a project repository and have different branches for things you want to try out. Keeping the working code in your master branch will prevent you loosing your working code. Also, when using a vcs you can always revert to versions of your code that have been working. The IntelliJ Idea IDE has perfect support for working with all different types of version control systems. If you don't want to learn any forms of vcs then there is no other way to "backup" your working code.
Is it proper procedure? It's probably not how most people would go about achieving what you want to achieve but it's certainly workable. If you wanted to stick with that for simplicity now, I'd copy the whole directory structure, delete the .idea and .iml files, and then create a new project in IntelliJ on that clean copy: IntelliJ will automatically set up folder structure based on the existing source without you having to go through any additional manual setup.
If you're willing to experiment with the git route, to achieve the basics of what you want to achieve is not very complicated and I've written a small quick-start below. IntelliJ offers very good support for Git, and once your repository is created you can do everything you need from the IDE. I'm going to assume you're working on Windows, although the steps shouldn't be too far removed on other platforms.
Install Git
You can download and install Git from https://git-scm.com/download/win, which will install a command shell called Git Bash.
One-off setup for your project
Open up git bash and go into the directory containing your source. Rather than seeing separate drives as Windows does, Git Bash assumes there is a logical 'root' directory under which all your files are accessible. Your C: drive will be /c. To move around you can use cd to change directory (using / instead of ) and ls to list files instead of using dir.
Assuming your source code is in C:\projects\myproject:
cd /c/projects/myproject
git init
The second line above creates a git repository in that directory. This doesn't affect your code, it just creates a folder called .git that contains all of the book-keeping information.
You don't want to have every file under version control - in particular you don't want your build outputs. You need to set up a file in your project directory called .gitignore which tells git which files and directories should be ignored. As a starting point you can copy https://github.com/github/gitignore/blob/master/Java.gitignore and rename the file to .gitignore
Basic Commands and committing your initial version
There are a small number of basic commands:
git status
Running git status will tell you which files have been modified, which are not under version control, and which files have been added to the staging area to be committed next time.
git add path/to/file
This adds a file to the staging area waiting to be committed. You can add multiple files to the staging area before committing them in one go.
git commit -m "description of your change"
This commits all of the staged files as a new version, which the specified commit message.
If you go into your project directory, do a git status and check through the list to make sure there's nothing you don't want to have under version control, then you can do git add . to add everything to the staging area and git commit -m "Check in initial version of the source code" to commit it to the repository.
After you've committed, you can run
git log
To see a history of all of the changes. IntelliJ has a view that will show you the same thing.
Creating an experimental branch
This is where git shines; if you want to try something experimental you can create a branch of your project while allowing git to preserve the original version.
git checkout -b experiment1
Will create and switch to a branch called experiment1. You can delete, rename, move, rewrite and develop whatever you like on this branch. The changes you commit will be independent of your original working version.
You can switch back to your original version (preserving all of the changes you've committed on that branch) using:
git checkout master
Where master is just the name of the default branch created when you ran git init. The experimental version will still be there and can be switched to again using git checkout experiment1 or from IntelliJ using the branch selection in the bottom right corner of the status bar.
If you decide that the changes you've made in experiment1 are to become your new "good" version, you can merge them back into the master branch and repeat the cycle from there.

How to roll back in subversion and simultaneously clear history?

My SVN repository contains several folders for different projects. 'Desktop program', 'iOS app', 'Web app' etc. All revision entries are shared between these (as it's under one repository. Revision #100 might be on the 'iOS app' folder, revision #101 on the 'Web app' folder etc).
What I want is to roll back to an earlier version on just one of these folders. Usually this is done with a 'reverse' SVN Merge as it's SVNs job to keep track of all history, even the bad times. I don't want that however. Lets say I have twenty commits on 'iOS app' since revision #5. I want to rid these from history and I want that specific folder to return to revision #5. No one should ever again be able to check those twenty commits as they 'never happened'. Is this even possible?
I have two different machines I am interacting to SVN with. A Windows PC with VisualSVN and a Mac with Subversion on Terminal level. I would be thankful for a solution on either.
From client side, there is simply no way to do this. No matter if commandline, Tortoise, or any other client.
If you have access to the server account that owns the repository, then there is some chance - but it is quite complicated and may involve a nontrivial manual work.
Roughly, these are the steps:
get the repository UUID - svn info http://svnserver/svn/repo - see the UUID line
dump the svn repository: svnadmin dump /path/to/repo > repo.dump
edit the dumpfile to exclude the commits
a) either open it in vi and delete your undesired commits
b) or use svndumpfilter command to filter them by path
create new repository and import your modified repository into it:
svnadmin create /path/to/repo2
svnadmin load < repo.dump
svnadmin setuuid /path/to/repo2 THE_ORIGINAL_UUID
Now, check that repo2 is working fine and has the content that you expect. If so, you can remove repo and rename repo2 -> repo.
Keep in mind that manual changes to the dumpfile are extremely prone to errors, and often these errors can be quite difficult to discover. It is usually bad idea to do things like this.
What I want is to roll back to an earlier version on just one of these folders. Usually this is done with a 'reverse' SVN Merge
Terrible... In order to return back part of WC-tree into some previous revision you have to cd SUBTREE-ROOT & svn up -r REVNO (commit from WC-root for this modified WC will create new revision in repo with partially rollbacked tree)
No one should ever again be able to check those twenty commits as they 'never happened'
Cheated and rewritten history in SCM is BAD IDEA. And Subversion history is immutable, you have to change history using svnadmin tools and access-level, as #petr-kozelka wrote

Bzr: Create a shared repository from an existing stand-alone repository

I have been using Bzr for version control of my project over the last few months. I am the sole developer, and currently I just have everything in a single local project directory, to which I commit and which I sync to DriveHQ.
I now have some large-scale experiments in mind which would likely break this main line, so I've been looking into the concepts of branches and shared repositories. So my question is, basically: how should I go about creating a new, shared repository from this already-version-controlled base?
I am familiar with the SVN project structure of trunk, branches and tags, and I'm going to adopt this structure. My plan is to just go ahead and do a fresh init-repo, and copy all my code (plus .bzr) over into the trunk folder. So is this OK? Or is there some way to convert what I have already into a shared repository?
Many thanks in advance for any help.
Christopher
OK, so you have some work directory where your standalone branch is.
You want to create trunk and feature branches in new shared repo.
At first you need to create a shared repository itself:
bzr init-repo /path/to/repo
Now you can put your code to repo/trunk. You can use push, branch or you can copy work and use reconfigure.
cd work; bzr push /path/to/repo/trunk
cd path/to/repo; bzr branch /path/to/work trunk
or copy/move work to /path/to/repo/trunk then cd /path/to/repo/trunk; bzr reconfigure --use-shared
In all cases you'll have branch trunk as a copy of your old work, and this trunk will use shared repository to save the revisions.
You can also look at bzr-colo plugin.
Create a folder outside your current repository.
Call bzr init-repo to create a shared repository
From your working tree push to the newly created shared repo.
You can now work directly on the shared repo

Bazaar offline + branches

I have a Bazaar repository on Host A with multiple branches. This is my main repository.
Until now, I have been doing checkouts on my other machines and committing directly to the main repository. However, now I am consolidating all my work to my laptop and multiple VMs. I need to be working offline regularly. In particular, I need to create/delete/merge branches all while offline.
I was thinking of continuing to have the master on Host A with a clone of the repository on the laptop with each vms doing checkouts of the clone.
Then, when I go offline, I could do bzr unbind on the clone and bzr bind when I am back online.
This failed as soon as I tried to bzr clone since bzr clone only clones a branch(!!!!)
I need some serious help. If Hg would handle this better please let me know (I need Windows support.) However, at this moment I cannot switch from Bazaar as it is too close to some important deadlines.
Thanks in advance!
bzr fundamentally works with one branch / directory (the branch are visible at the file system level), so if you need to clone each branch from your repository (not unlike svn, in a way). Hg, at basic level, works this way too (although you can put several branches in one repository using say named branches).
For DVCS, it is important to distinguish between the following:
Working tree: a versioned set of files (at a given revision)
Branch: a linear set of revisions
Repository: a set of revisions
When you clone locally a directory versioned by bzr, you are copying the repository subset which contains all the revisions in the branch you are cloning, and get the working tree. This assumes you are not asking for a branch wo a working tree nor using a shared repository.
What you want, IIUC, is to clone the full repository with all the branches. There is no 'native' way to do so in bzr I believe, but plugins to help you toward this, like multi-pull and push-repo, to sync multiple branches in one shot.
But I don't understand why that's such a big problem, or the link with working offline: you just clone the branches you want to work on your laptop.

How to dcommit only selected patches with git svn?

I have a number of locally committed patches in my git-svn repo which I haven't yet commited to our svn repo. A normal "git svn dcommit" will commit all of these patches to svn. I would like to commit only some of my patches (simple bug fixes), but not others (untested major changes). How can I do this with git svn?
I've been following the procedure here:
http://fredericiana.com/2009/12/31/partial-svn-dcommit-with-git/
If you're comfortable rebasing, it works pretty well.
Here's what I ended up doing. The starting point is the "master" branch synced with svn, with all of my local patches on top.
Create a new branch (wip = Work In Progress).
git branch wip
This makes a copy of the current branch, including all patches not yet committed to svn. The current branch will stay as "master" and will not be changed.
Remove the unwanted local patches from "master" with a rebase:
git rebase -i HEAD~10
Now the "master" branch has patches you can safely commit:
git svn dcommit
The "wip" branch now has the major changes which aren't yet ready for sharing. Actually, I want them to stay there and this is where I would stop. It's possible to do the svn dcommit from the "wip" branch once everything is finalized. But for completess' sake, and to answer the original question, there's a final step:
Pull the uncommitted changes back to the "master" branch using git cherry-pick and finally remove the useless branch with git branch -d wip.
With git, you're not actually supposed to operate on single changesets. The best approach I know is to create local branches for any non-trivial work. This way, your untested major changes will end up in different branches of your git repository, and you'll be able to differ them quite easily.
If this is the problem you have at the moment you can probably create create a new branch from the point you last updated from svn and then use git-cherry-pick to transfer your simple bug fixes to this new branch, from which you can then dcommit to svn.
From a more long-term point of view it's best to have your own "master" branch made from subversion trunk, and then either:
Rebase all your branches every time you update from svn, then merge those you want to get to svn to your master and dcommit from there.
Merge stuff from svn using regular git-merge, and then merge stuff to your master for dcommits by git diff ..my_branch | patch -p1, which will eliminate history that git-svn can't handle. This approach is more complicated for the final merging but allows you to merge stuff between branches (and possibly other people) in git itself.