One PR created two commits in SVN server side

Hi Team,

in Bitbucket we are using svn mirror plugin to synch svn to bitbucket, and user recently merged the one PR in bitbucket and it got created 2 commits in svn

user did below

  1. changed one of the files in this path <banchname/src/comp_name/filename.c>
  2. raised a PR from his feature branch to mirror branch
  3. and merged the PR
  4. it got created 2 commits in svn side

below are the 2 commits

  • one commit is created for the change on “banchname/src/comp_name/filename.c” (svn rev is 92)
  • the second commit added in svn on “banchname” with PR details (svn rev is 93)

below is the raw diff from svn for 2nd dummy commit, please check and advise

Index: branchname

— branchname (revision 92)
+++ branchname (revision 93)

Property changes on: sm/branches/6.3


Added: subgit:lock:041412e5732f117a19c6e4db327f7fd9241b88c5

-0,0 +1

+2022-11-14T09:21:03.133
\ No newline at end of property
Deleted: subgit:lock:f6e2075c96dab531b4ddc68d44c73cc496aa96b1

-1 +0,0

-2022-11-14T09:20:52.316
\ No newline at end of property

Hello,
from this information, I can’t say why this happens. But there’s a way to find that out.

First of all, subgit:lock:* is just a special property that is set on each branch root to be changed. It is needed to forbid concurrent modifications of the branch by several SVN clients (one of which is SVN Mirror), so you can ignore it. But this property contains important information because its format is

subgit:lock:<SHA-1 of Git commit>

From that I would suppose that

  • f6e2075c96dab531b4ddc68d44c73cc496aa96b1 was translated to r92; and
  • 041412e5732f117a19c6e4db327f7fd9241b88c5 was translated to r93.

So, there’re 2 new SVN revisions becase there’re 2 Git commits: f6e2075c96dab531b4ddc68d44c73cc496aa96b1 and 041412e5732f117a19c6e4db327f7fd9241b88c5.

Now the question is why there’re 2 Git commits.

To analyze the situation further I would recommend you:

  1. To run
git log 041412e5732f117a19c6e4db327f7fd9241b88c5

and see if f6e2075c96dab531b4ddc68d44c73cc496aa96b1 is mentioned in the output, e.g. if
f6e2075c96dab531b4ddc68d44c73cc496aa96b1 is a parent commit of 041412e5732f117a19c6e4db327f7fd9241b88c5.

I would expect that yes, it is the parent, but it’s better to be sure. Another possible option: these 2 commits are not related to each other and reside in separate Git branches, that would be unexpected.

  1. If “f6e20…” is the parent of “04141…”, run
git diff f6e2075c96dab531b4ddc68d44c73cc496aa96b1 041412e5732f117a19c6e4db327f7fd9241b88c5

To see what has been changed in 041412e5732f117a19c6e4db327f7fd9241b88c5 compared to f6e2075c96dab531b4ddc68d44c73cc496aa96b1. I would guess that only “untranslatable” (i.e. excluded from translation by “excludePath=” option) files are changed. If this is so, this could explain why the SVN revision is basically “empty” (i.e. changes nothing).

There’s an option named translate.createEmptySvnCommits that controls whether such “empty” SVN revisions should be created or skipped. So you can set

[translate]
  createEmptySvnCommits = false

and “Apply Changes” if you want to skip such empty revisions. By the way, there’s a similar option (translate.createEmptyGitCommits) for the opposite situation: when SVN only contains changes that can’t be translated to Git.

  1. Finally, it’s interesting to find out, why 041412e5732f117a19c6e4db327f7fd9241b88c5 was created. As I understand, f6e2075c96dab531b4ddc68d44c73cc496aa96b1 (i.e. r92) corresponds to the merge of the PR. But what’s the purpose of 041412e5732f117a19c6e4db327f7fd9241b88c5 (r93) is not clear. Could you deduce that from the commit message of 041412e5732f117a19c6e4db327f7fd9241b88c5 or of r93? Do they have the same messages? I would guess that simply someone could have committed to the same branch right after you’ve merged the PR (r92). Is that possible?

Hello,
I wonder if

git log --graph 041412e5732f117a19c6e4db327f7fd9241b88c5

draws a structure like the following one:

(this could explain everything)

Or does it draw something like:
structure2

I think, the problem is that unlike SVN, Git keeps no information which commit should come to which branch and we’re using heuristics to find out, which Git commit should go to which branch. And probably in that case the heuristics have [incorrectly] detected that both commits (f6e2075c96dab531b4ddc68d44c73cc496aa96b1 and 041412e5732f117a19c6e4db327f7fd9241b88c5) should go to to “sm/branches/6.3”, while only the last one should (note: that “bugfix/JIRA--coverity-cid--branchname” is not configured for translation, so SVN Mirror doesn’t sees it and thus doesn’t understand that actually f6e2075c96dab531b4ddc68d44c73cc496aa96b1 belongs to it).

Maybe it is even better in case when the bugfix consists not only of one commit like in your case, but of many commits: then they would come to SVN as separate revisions.

What about the effect of

[translate]
createEmptySvnCommits = false

Yes, you can add it and apply changes. As result, all Git commits that change nothing (like 041412e5732f117a19c6e4db327f7fd9241b88c5 compared to f6e2075c96dab531b4ddc68d44c73cc496aa96b1) or Git commits changing “.gitignore” files only (when .gitignore files are explicitly excluded) — they will not be translated to SVN as separate revision.

E.g. if you have
commit1 —> commit2 —> commit3
and “commit2” changes no file or changes only files that are excluded from translation (like maybe .gitignore files), only 2 new SVN revisions will be created: one for commit1 and one for commit3. And in the scenario above an empty revision wouldn’t be created.

Fortunately, you can turn this option on and off and apply changes whenever you want: the effect will only apply on new revisions created since clicking “Apply Changes”.

This is exactly the triangle I’ve drawn on my first picture, so my guess was correct. I hope, “createEmptySvnCommits = false” solves the problem for you.

Hi Dmitry,

where we can add these changes? is this under “Branches Mapping” like below ?

Subversion to Git mapping options

[svn]

[translate]
createEmptySvnCommits = false

Thanks,
Manju NS

Hi Dmitry,

can you please confirm on above?

where exactly we need to add this “createEmptySvnCommits = false” ? is this under is this under “Branches Mapping” configuration ?

Thanks,
Manju NS

Hi Manju,

yes, that’s correct, those settings should be added under “Branches Mapping” like you mentioned:

[svn]
    trunk = …
    branches = …

[translate]
    createEmptySvnCommits = false

Hi ildar,

Thanks for the confirmation, will update and get back to you

Hi Dmitry/ildar,

I have added the above config changes and still we are facing the issue, can we have a quick call on zoom , we can available for next 1 to 2 hour

Thanks,
Manju NS

Hello,
I’m available for the call.

Hi Dmitry,

can you please join with below zoom link?

Thanks,
Manju NS

I’ve discussed the problem with my colleague and he told me that SVN Mirror already has the option that would change behaviour to exactly the one you want. It’s called translate.followFirstParent.

You specify it under [translate] section:

[translate]
  followFirstParent = true

and apply the change. Since then you’ll get a single SVN revision for each pull request merge.

Thanks,

will try and get back to you :)

I would also recommend to prefer

git pull --rebase

command over just

git pull

for individual Bitbucket users when using this option. This is not a strict rule, both variants would work, but in some scenarios the second variant (“git pull”) may produce worse results, while “git pull --rebase” always works fine. This is so because “git pull --rebase” in some sense simulates Subversion workflow and thus is more natural when using SVN Mirror.