I accidentally updated to a previous revision, and committed from it under the default branch, causing 2 heads under the default branch. I want to move one of the heads to another branch. This head I want to move was made a couple transactions ago. How can I change the branch it is a part of so that I can push the other head to the server without a force push?
I have not pushed anything to the server so far. If it comes down to it, I can copy the files I need and reclone the repository.
Rebase
Graft (move to new place) + Histedit (kill old changeset)
MQ, if you know it (convert cset to MQ-patch, update to new parent, qpop, qfinish)
You can rewrite the history with the rebase extension. It's already installed, you just need to enable it (from File > Settings > Extensions in tortoiseHG). Inside tortoiseHG you can find it if you right-click on a revision, go to "Modify History", and choose "rebase". But for more control I recommend dropping to the commandline.
Let's say you have a revision w that's a new head off the default branch. (w might have descendants which will move along with it).
-o-o-o-o
\
w
Its parent should have been some revision b in another branch (not shown). Just enter:
hg rebase --source w --dest b --detach
That's it! It will rebase w and all of its descendants (if any), so that its new parent is b. It will be assigned to the same branch name as b, unless you add --keepbranches. The flag --detach ensures that you don't end up with a complex topology under some circumstances.
Related
i try to Checkout a Remotebranch via LibGitSharp. In git itself you use this comands:
git fetch origin
git checkout -b test origin/test
in newer Versions it is just:
git fetch
git checkout test
So i tried this Code:
repo.Fetch("origin");
repo.Checkout("origin/" + Name);
The Fetch and Checkout runs without any problems but there is no copy of the Remotebranch.
Does anyone have an idea to Checkout the Remote with other methods?
My alternative would be to create the Branch in the Repository and push it into Remote:
Branch newBranch = repo.Branches.Add(Name, repo.Branches["master"].Commits.First());
repo.Network.Push(newBranch);
but i get this Exception:
The branch 'Test1' ("refs/heads/Test1") that you are trying to push does not track an upstream branch.
maybe i could set the Branch to an upstream Branch, but i don't know how.
Edit: I haven't explained it properly, so I try to describe it better what the Fetch and Checkout does in my program. The Fetch command is performed correctly. Now if i use the checkout command it should be create an local Branch of the Remotebranch, but it doesn't. I've also tried repo.Checkout(name), without "origin/" ,but it cast an Exception: No valid git object identified by '...' exists in the repository.
If I correctly understand your question, you're willing to create a local branch which would be configured to track the fetched remote tracking branch.
In other words, once you fetch a repository, your references contains remote tracking branches (eg. origin/theBranch) and you'd like to create a local branch bearing the same name (eg. theBranch).
The following example should demonstrate how to do this
const string localBranchName = "theBranch";
// The local branch doesn't exist yet
Assert.Null(repo.Branches[localBranchName]);
// Let's get a reference on the remote tracking branch...
const string trackedBranchName = "origin/theBranch";
Branch trackedBranch = repo.Branches[trackedBranchName];
// ...and create a local branch pointing at the same Commit
Branch branch = repo.CreateBranch(localBranchName, trackedBranch.Tip);
// The local branch is not configured to track anything
Assert.False(branch.IsTracking);
// So, let's configure the local branch to track the remote one.
Branch updatedBranch = repo.Branches.Update(branch,
b => b.TrackedBranch = trackedBranch.CanonicalName);
// Bam! It's done.
Assert.True(updatedBranch.IsTracking);
Assert.Equal(trackedBranchName, updatedBranch.TrackedBranch.Name);
Note: More examples can be found in the BranchFixture.cs test suite.
I am trying to add submodules support to a project of mine, however I seem to be unable to use JGit to read specific commits or to log, while commandline git can do this just fine, despite the detached head that the submodule is in (as far as by design of how submodules work).
I have code like this, with "fuse-jna" being the submodule:
FileRepositoryBuilder builder = new FileRepositoryBuilder();
Repository repository = builder.setGitDir(new File("fuse-jna/.git"))
.readEnvironment() // scan environment GIT_* variables
.findGitDir() // scan up the file system tree
.build();
ObjectId lastCommitId = repository.resolve("39c1c4b78ff751b0b9e28f4fb35148a1acd6646f");
Iterable<RevCommit> commits = new Git(repository).log().add(lastCommitId).call();
for(RevCommit commit : commits) {
System.out.println("Commit: " + commit.getId());
}
with this I get:
org.eclipse.jgit.errors.MissingObjectException: Missing commit 39c1c4b78ff751b0b9e28f4fb35148a1acd6646f
at org.eclipse.jgit.internal.storage.file.WindowCursor.open(WindowCursor.java:149)
at org.eclipse.jgit.revwalk.RevWalk.getCachedBytes(RevWalk.java:883)
at org.eclipse.jgit.revwalk.RevCommit.parseHeaders(RevCommit.java:145)
at org.eclipse.jgit.revwalk.RevWalk.markStart(RevWalk.java:279)
at org.eclipse.jgit.api.LogCommand.add(LogCommand.java:330)
at org.eclipse.jgit.api.LogCommand.add(LogCommand.java:189)
at org.dstadler.jgitfs.util.JGitHelperTest.testGitLinkRepository(JGitHelperTest.java:638)
However on the commandline in the "fuse-jna" directory
git diff 39c1c4b78ff751b0b9e28f4fb35148a1acd6646f~
works just fine, so it is possible to do this.
Is there some other way how to do this with JGit? Or is support for submodules not fully there yet?
Seems the trick is to not open the repository of the submodule like a normal Git repository, but use the JGit class SubmoduleWalk and the parent-repository to do this!
The following did work for me after playing around with it some more:
Repository subRepo = SubmoduleWalk.getSubmoduleRepository(repository, "fuse-jna");
I'm looking for a way to create (not update) a trac ticket in response to a commit message like "Hack code to not kill your dog (TODO: fix this properly to avoid chasing kittens instead)".
I want the trac system to react on the "TODO" keyword and create a ticket with the content of the commit message, the owner set to the committer and the opening commit already referenced.
While searching on SO I found Open and close trac tickets with a single commit which basically says how I could roll my own solution. Which I'd do if there isn't a pre-made one available. So - is there?
I would suggest looking at the official Trac package for python: http://pypi.python.org/pypi/Trac/0.11.4 and docs http://www.edgewall.org/docs/tags-trac-0.11.7/epydoc/trac-module.html
This is what we use to create tickets in Trac from a python script and I think it's fairly simple to use. You could run this python script as a post commit hook for your VCS.
You can start up a trac environment using your project settings and then new up tickets and save them. There's probably a little more to it for you, but this should give you a good idea:
from trac.env import Environment
from trac.ticket import Ticket
env = Environment(projectSettings, create=0)
tkt = Ticket(env)
tkt['summary'] = 'first line of commit message'
tkt['description'] = 'full commit message'
tkt.save_changes(commitAuthor, '')
Needless to say, current Trac stable is 0.12.3, but of course development needs to go with your current version. (You didn't tell us in you question.)
On you question, there is a hint on how to implement different functionality on-top of the CommitTicketUpdater from Trac core. It has update and close as built-in actions, so you'll need to do some change like so (based on current Trac trunk):
create an additional option commands_create for commands, that create a new ticket with reference to the changeset, as a space-separated list
add a class-wide variable self.comment in both of changeset_added and changeset_modified right after comment assignment
add a module cmd_create like (untested)
def cmd_create(self, ticket, changeset, perm):
if not self.check_perms or 'TICKET_CREATE' in perm:
# Commit messages in general is used for a ticket comment.
# New tickets require summary and we'll want description too,
# because comment is ignored on ticket creation.
# So we need to do message processing here beforehand.
ticket['comment'] = None
ticket['description'] = self.comment
ticket['owner'] = changeset.author
ticket['status'] = 'new'
ticket['summary'] = ' '.join(['TODO from', str(changeset.rev)])
ticket.insert()
alter ticket_command so the regexp matches not only the default function-ticket(s) pairs but the unary 'TODO:' as well (sorry, can't make this working right-away now)
extend the private module _parse_message to include another case before if func:
if cmd.startswith('TODO'):
tickets.update({None : ['create']})
continue
change _update_tickets to make the comment saving conditional, because you won't need/want an additional comment on new tickets)
if ticket['comment']:
ticket.save_changes(changeset.author, comment, date, db)
Ok, ask back as required, if you like to try this approach.
Allright I got myself in a deadlock with Mercurial and sub-repos... Here's what happenend:
I had a large mercurial repo that I server via apache and hgweb.cgi.
Due to the size of the repo I decided to move to sub-repositories and share these with hgwebdir.cgi.
Using the convert tool with the filemap option I created several sub-repositories:
/main/foo
/main/bar
Nicely created an entry for the sub-repositories in .hgsub:
foo = foo
bar = bar
And set hgwebdir.cgi up to show $/** as the root folder.
Now when I went to my site (foo.com/hg) I saw my sub-repositories with one empty reposory among them (no name, no content), but I could not download it (archive location unknown):
empty_repo http://img707.imageshack.us/img707/8237/emptysubrepo.png
That was allright until I added a new sub-repository.
I could not push the new .hgsub file to foo.com/hg, since that page is served by hgwebdir.
The only method I can work currently is switch from hgwebdir to hgweb, commit .hgsubste and switch back to hgwebdir.
Does someone have a good setup for such a mess?
On the webserver your main and its subrepos should appear as siblings -- not with the subrepos inside main.
Main
ASCII
AlignDistribute
And the URLs in your .hgsub should look like:
ASCII = ../ASCII
AlignDistribute = ../AlignDsitribute
Then you'll be able to push/pull to http://foo.com/hg/Main and when you clone it the clone/update will automatically attach and clone down the separate subrepos.
From what I've read on https://www.mercurial-scm.org/wiki/PublishingRepositories#multiple
The keys (on the left) and the values (on the right) are both filesystem paths
The keys should be prefixes of the values and are "subtracted" from the values in order to generate the URL paths to each repository
What I'm guessing happened is that in your hgweb(dir) configuration you're specifying the same value for a collection possibly as the key, so during subtraction it ends up with a blank name and no way to get to it.
When I use [collections] to set /a/full/path = /a/full/path directly to a repo, it'll end up blank too, because it's reading that folder as a repo because it is a repo, instead of each sub-directory being an individual repo, after I removed the .hg folder and .hgsubs and everything from the root of my collection entry, all the subfolders started showing up properly.
I originally used in [paths], /path/to/my/project = /path/to/my/project, and since that is a single referenced repository, it'll subtract the value from the key, leaving you once again with '', instead I used project = /path/to/my/project and it came out as 'project'.
Hopefully that URL or these descriptions will get you out of your pickle!
I am trying to branch a file in ClearCase Remote Client.
I have the branch set up and the config spec is updated to handle the branch.
But I can't find the option, and the googling isn't helping much.
The way I understand your question, it sounds like you want to somehow select a command from a Clearcase RC menu(s) and have the branch explicitly created(?)
Clearcase has no explicit "Generate Branch for this File" command; you would want the "Checkout" command in this case. Branching is indirect and is a result of checking out a version of a file in a view that has a config spec with the '-mkbranch ' operation in it. I.e. the following config spec will create the dev_1.0_branch once I check it out (for any and all vobs and files):
element * CHECKEDOUT
element * .../dev_1.0_branch/LATEST
element * /main/LATEST -mkbranch dev_1.0_branch
The first line is standard for views in which you are doing development, line 2 will assure that I see any file that has a dev_1.0_branch (particularly important for the checkout+mkbranch to work as expected :-), and line 3 will select the latest version of any file that does not have a dev_1.0_branch and will create the branch if (and only if) the file version selected by that rule is checked out.
Please let me know if any of the above sounds greek to you, particularly any of the config spec rules. Having worked with ClearCase for a long time, I assume and use a lot of its terminology and concepts as if it's common knowledge :-P.
One thing of note: if you checkout the file, then immediately uncheckout the file, you will leave an empty branch on that file (i.e. in the above you would have a file with a version such as: foo.c##/main/dev_1.0_branch/0, but no /main/dev_1.0_branch/1 version). Many sites prefer to keep the version tree clean and remove empty branches (one can be found in this IBM Rational Technical article)
Just to be clear, I'm familiar with ClearCase Base & ClearCase MultiSite, but have not worked with the Remote Client yet.
--- 2009-Jun-29 Update
In response to Paul's comment below, if you want to be selective in what files are branched, you can modify the "*" to be more specific. For example, if you want to only branch foo.c in the FOODEV VOB, but leave everything else on main:
UNIX config spec:
element * CHECKOUT
element * .../my_dev_branch/LATEST
element /vobs/FOODEV/src/foo.c -mkbranch my_dev_branch
element * /main/LATEST
(For windows, you would want to use Windows conventions. I.e. \FOODEV\src\foo.c).
You can also select a directory and all elements below the directory (again UNIX config spec):
element * CHECKOUT
element * .../my_dev_branch/LATEST
element /vobs/FOODEV/src/mycomponent/... -mkbranch my_dev_branch
element * /main/LATEST
The main page for config_spec (cleartool man config_spec from the command line on windows or unix) provides decent guidance in the "Pattern" section for how to write the element/version selector (2nd column).
You can do a lot of complex version selection with the config specs. Please let me know if you would like more details or specifics.
Here's a config spec that I used for fixing a particular bug, with names changed to disguise some of the guilty.
element * CHECKEDOUT
element * .../TEMP.bugnum171238.jleffler/LATEST
mkbranch -override TEMP.bugnum171238.jleffler
include /clearcase/cspecs/project/version-1.23.45
To create the branch, in each VOB, I used a command:
ct mkbrtype -c 'Branch for bug 171238' TEMP.bugnum171238.jleffler#/vobs/project
Previously, we used config specs with -mkbranch rules appended to the various element lines.