How should I structure my git-svn workflow to avoid "revision1 is merged into revision2, but does not have git-svn metadata" - version-control

I am using git-svn in my workplace since our current version control server is subversion and switching completely to git does not seem to be on the horizon for now (*cry*)
My workflow is as follows
I have the following branches
master tracks remotes/trunk
local/0.4 tracks remotes/0.4
work is my development branch for the master branch
work-0.4 is my development branch for the local/0.4 branch
I work in my work branches, then I merge to master and local/0.4 using
git merge --no-ff <branchname>
After that I check in to svn via
git svn dcommit
and I use
svn.pushmergeinfo=true
to update the svn:mergeinfo properties so my colleagues won't get angry with me messing up that metadata for them :)
However, I just had the following problem which stumps me.
I had done two commits on the work-0.4 branch, then I merged these to my local/0.4 branch with git merge --no-ff work-0.4. After this, I did git svn dcommit and recieved the following message
Committing to https://svn-server ...
e138050f6ebd2f2ca99cbefc5e48acae412e1f86 is merged into revision f5f2345e8e5fc64
20423bdc00397b5853b3759c4, but does not have git-svn metadata. Either dcommit the
branch or use a local cherry-pick, FF merge, or rebase instead of
an explicit merge commit.
After some rebasing and reset'ing of branches I managed to push everything to svn, but my solution entailed doing a rebase of my local/0.4 branch to the work-0.4 branch which in turn meant that I did not get to squash my two git-commits into one svn-commit :/
I feel that I'm probably doing something wrong with my workflow here, and it might be related to svn.pushmergeinfo. The docs for svn.pushmergeinfo says
config key: svn.pushmergeinfo
+
This option will cause git-svn to attempt to automatically populate the
svn:mergeinfo property in the SVN repository when possible. Currently, this can
only be done when dcommitting non-fast-forward merges where all parents but the
first have already been pushed into SVN.
and to be honest, I'm not quite sure that I understand that correctly? Am I doing something weird here that makes svn.pushmergeinfo not work correctly? How should I structure my workflow to optimally work with git-svn correctly (setting proper mergeinfos etc)?

Related

How to merge to a branch that is behind in network in Gitlab?

I am quite new with Gitlab and I'm having an issue for merging in Eclipse.
We're working as a team, and we all have development branches that we are trying to merge into a single one. Unfortunately, when I did my merge, I have done a stupid mistake. Instead of merging my development branch to the main one, I have merged the main one into my development branch.
I have reversed the commit/merge on gitlab, but now as I try to merge back my development branch into the main one on Eclipse, it seems like I am 9 commits ahead of this branch (described as the arrows on Eclipse here: ), so the potential merge would basically replace everything by my code, when I should actually have merge conflicts to solve.
I am not quite sure how to merge properly so that I get back these merge conflicts.
Here is a screenshot of my network:
The ['1'] commit in the network on the left branch (my branch) corresponds to the merge from Week6AllIssues to my dev branch (the wrong merge). The last commit on this left branch is me reversing the commit.
Thanks a lot for your help !
If you're not using the remote branch with anyone else, the following series of steps might help.
First, remove the superfluous commits from the local branch. It can be achieved with git reset --hard <the commit before you merged master into your branch> command (see this link on how to do this with Eclipse).
Now make the remote branch match your local branch. You can do this with git push --force command. In Eclipse, this command corresponds to configure push - enable "force update" option.
Now the superfluous commits are gone.

Git-SVN: how can i merge branch to trunk?

I am working on a git-svn project with two branches, lets call them
trunk
branches/foo
How can i merge branches/foo to trunk?
they both have the latest update
Thanks
It is inadvisable to merge two SVN branches via Git. If in Git you merge from your branches/foo clone to your trunk clone and then managed to successfully push back to SVN, the files would be correctly updated on trunk, but SVN wouldn't be aware that it's the result of a merge - no merge-tracking information will be updated in SVN.
In fact it gets more complicated than that - when you merge between two Git branches that are both tracking remote SVN repos, git-svn can get really confused and it's very easy to mess up your repository. This is because git-svn looks back through your Git log to find the SVN tracking information, and if it finds a merge then it won't necessarily head down the branch you expect. So even if you've merged from branches/foo into trunk and you're now on trunk, it's possible that a dcommit would push back to branches/foo.
Better to switch back to your regular SVN tools to do merges and just use git-svn for development.
Another roof option could be next:
checkout your trunk branch # git checkout -b trunk git-svn-trunk
and cherry-pick dev commits into trunk branch,
i prefer pick one by one and solve conflict slowly
after that you have a 2 branches with the same commits
maybe do you want remove dev branch and create a new dev branch from trunk branch,
now this branch (new dev branch) has a correct git-svn reference to your svn trunk...
keep recommendations write by #simonp answer
i hope this help to you

looking for ideal git-svn workflow

The company that I'm working is working with SVN but I would like to start working with git to take advantage of the light branching and stashing features (disclaimer, I'm pretty new to git). I've started with git-svn and I'm trying to figure out the ideal git-svn workflow for what I'm trying to do (and suggestions if what I'm trying to do needs tweaking).
I've read through git svn workflow - feature branches and merge and a few other posts but its still not clear how I should approach it.
How I plan to work:
I plan on having my master branch be clean from development and only used for merging/rebase/dcommit.
I would like break apart each new feature/bug into separate git branches so they can be worked on independently. Meaning, I can work on one feature for a few hours, then put it aside and work on the next issue. When I was in SVN it was a problem when I had two different features/bugs in one file because when it came time to commit, I would remember that it had both changes and temporarily take out what I didn't want to commit now - a pain.
And the are some features which are while I might want to work on now, will not be added to the main repo for some time.
After a feature is ready to be shared/tested in the main repo, I'll merge/rebase into my master branch and then dcommit to the svn-repo. I only want to have one SVN commit message for each dcommit - I want to be committing in more often with comments more specific to me and then dcommit to svn with a message for the rest of the team. I assume for this I'll either be using a git merge --squash or a git rebase --interactive for this.
The basic git flow I've envisioned is like this:
// it begins...
git svn clone <repo>
//
git checkout -b feature 1
// work commit, work commit
//
git checkout -b bug-123
// work commit, work commit
// bug-123 finished - ready to send back
// got back to master for step 5
git checkout master
// get whatever changes other devs did
git svn rebase
//
git checkout bug-123
// rebase branch so I have fewer smaller changes. not sure here..
git rebase master || git svn rebase
// Assuming I'm doing a FF rebase so my commits are just addons to the current repo
// I don't know if I rebase the master or svn repo or it doesn't matter.
// need to get my changes back to master to send off
git checkout master
// add my changes to master
git rebase bug-123 (--interactive?) || git merge --squash bug-123
// do I add a new commit message here?
// push my changes back out to the team
git dcommit
So there are a few questions:
How should I get the changes into the branch I want to commit - by rebasing the master or the svn branch
how do I get the changes back into the main branch - rebase or merge - remember, I want only one commit for each commit - unless this is going to complicate things - I really would prefer to keep my git commits separate from the SVN commits because I might start something - it's half-working, and want to commit it so I could try something else - but I don't want to commit these broken steps.
would it make sense to dcommit directly from the working branch (eg bug-123)?
how do I get the changes from bug-123 back now into feature-1? I'm assuming I'll do it via the SVN repo - meaning the changes that I added will get merged in when I do the rebase when it's time to add feature-1 to the repo - but maybe not.
I'm no expert, but these are the experiences I've made (related answer).
I think it doesn't matter. The important thing is that you rebase the latest changes from SVN into the branch you are going to dcommit from.
Let other branches receive the changes through SVN. If you want a single SVN commit from a series of git commits, squash them together first.
I think this doesn't matter either. You're going to rebase the latest changes from SVN, and need to get them linearly in front of your Git commits. If you do git svn rebase in master, and then rebase master into a feature branch, or the other way around is same-same. Afterwards you probably want to delete the branch, as it has done its work (as per SVN restrictions, you're not allowed to merge again).
Always let changes flow into other branches and repos through SVN rebasing.
Just try it out and try to get the most simple/practical workflow for you and your team. Try to keep branches short-lived (SVN won't get any notion of them anyway), and remember that the commits must always be linearized at the top of your log before you dcommit back.

How to handle merges with hgsubversion?

I am trying to contribute to a project that uses Subversion. I used Mercurial and its hgsubversion extension to clone the repo. My work takes place on a feature branch.
How do I keep the feature branch up to date with stuff that happens on the default branch (hg speak) aka the trunk (svn speak)?
So I used hg up feature to update to the feature branch, then hg pull which gave me changesets on the default branch. So I did hg merge default, the committed the merge, then tried hg push to send my changesets to Subversion. And Mercurial said: "Sorry, can't find svn parent of a merge revision."
I have finally figured out how to get my repository un-wedged after an event like that described in the question, so that I can continue work without having to re-clone the parent repository (which is, obviously, a quite slow operation when you are pulling from Subversion!). If the "tip" of Subversion outruns you so that you cannot push any more, just make sure that you have the built-in "rebase" extension activated in your Mercurial through a $HOME/.hgrc line like this:
[extensions]
rebase =
And then you should be able to run this command when your repository gets wedged:
$ hg rebase --svn
If I understand this correctly, it dissolves your current branch that has taken you away from Subversion HEAD, and rebuilds it atop the branch "tip" in Mercurial that corresponds to the HEAD in Subversion. From there, you can keep working and successfully do pushes again. It has always worked for me so far; let me know if you run into any problems!
Mercurial as a few different branching modes: http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/
The one you're describing is 'named branches', which is the most popular when you're working with a repo that's accessed only via mercurial (or hg-git).
However, when you're using hg-subversion so that you're pushing changes to/from subversion, which only nominally has branches, you're better off keeping all of your mercurial changes in the 'default' named branch, and using the 'clones and branches' pattern (which I prefer anyway).
Specifically, that message Sorry, can't find svn parent of a merge revision. isn't a descendant of a revision that has a direct match in subversion.
Were I you, I'd reclone from svn, and then move my work into that repo's 'default' branch with the 'transplant' command (packaged extension). If you want multiple features in parallel w/ hg-subversion use separate clones (they're so cheap), as it's more in line with how subversion thinks about branches.
I needed to figure this out for myself and wrote it up here:
http://notebook.3gfp.com/2010/05/pushing-a-new-feature-from-a-mercurial-repo-into-an-svn-repo/
I haven't yet figured out how to close a branch in subversion and have the mercurial graph look correct.

How to develop on a branch in HG?

I would like to do some experimental work in a hg project. So I would like to create branch, commit to it. And if the experiment works, I can merge it back to main branch.
In git, I can do
$ git branch experimental
$ git checkout experimental
(edit file)
$ git commit -a
$ git checkout master
I've read A Guide to Branching in Mercurial. It said hg branch feature. But what is next?
I don't follow.
$ hg branch experimental
(edit file)
$ hg commit
$ hg update default
First note that git branch is different from hg branch. Branches created with hg branch are permanent and live in a global name space, whereas branches made with git branch are transient. The nearest equivalent of git branch is hg bookmark: bookmarks can be renamed and deleted and behave more like Git-branches.
I've recently written a guide for Mercurial bookmarks. Compare this with the named branch guide. Both guides contain worked examples of how to use (named) branches in Mercurial for keeping track of the development. It shows how to merge branches and how to close them or delete the bookmark when you are done.
If it's not a big feature (i.e. the branch doesn't have to have a name), it's quite simple.
Let's say your repository is at changeset X. You work on the feature as much as you like, commit, commit, commit and if you're happy with the result, continue as if you knew it would work all along. ;) If you aren't happy, do a hg update X and continue development from there. All the work you did on your experiment will become an anonymous branch.
Strangely enough, it appears that Git doesn't provide such a way to work with anonymous branches which is what might be confusing you.