I was working in the wrong repo. They are almost the same but not associated data. How do i diff/merge? - version-control

Can you diff with the reverted copy?
I was doing work in the wrong repo. They are almost the same, but have no actual relation.
I just did a pull and an update, can i then copy my changed files into the Right head and then run a diff on it or something similar and then properly merge the 2 together?
I feel an alternate option would be do something like
copy the code over and commit it, then revert back, and merge with the commit to diff what has all changed..
I have changing something like 1500 lines over 9 files, so i dont want to rewrite a bunch of code segments.
How should i handle this?

It really depends on how similar the "almost the same, but have no actual relation" repositories are.
If they extremely similar (as in files have the same names and text is almost identical), you might get by with exporting a patch at the source repo and then importing the same patch into the target repo.
In the source repo:
hg export -r tip > path\to\oops.patch
and in the target repo:
hg import path\to\oops.patch --no-commit
I used --no-commit since I assume you will need to do some cleanup first to make sure that everything looks ok.
Alternatively, you could just compare the two directories using kdiff or BeyondCompare3 and bring over the differences that you want from the source repo to the target repo and commit it that way. This would probably be my approach.
(I am intentionally ignoring the question about why you have two repositories that are that similar but don't have a shared history. For all I know, it might be the right thing to do.)

Related

Mercurial merge results in files labelled modified but which are binary equal

I'm in the process of doing a merge, and I'm ready to commit at this point but my commit dialog in TortoiseHg is showing many files as modified but when I diff to parents it says all files are binary equal.
I do not have and have never had the eol extension enabled.
Revert changes nothing, the file is still registering as modified.
hg parents shows two parents for the file.
hg stat shows the file as modified, e.g.
c:\Projects\MyProject>hg stat Authorization\AuthorityGroups.cs
M Authorization\AuthorityGroups.cs
hg diff --git shows nothing, e.g.
c:\Projects\MyProject>hg diff --git Authorization\AuthorityGroups.cs
c:\Projects\MyProject>
I've tried this on two different machines on two separate clones and I'm seeing the same thing.
Any other thoughts for how I could diagnose or fix this?
Clearly something has changed but if it's not showing in hg diff --git how can I establish what that might be?
Update 2014/12/10:
I've done a bit more checking on the history of the two parent revisions and I think I see why it's getting confused.
We've got the original parent file added in revision 1 on default.
On the Apple branch the file has been renamed to move it to a new location.
On the Orange branch the file has been added to move it to the same new location.
So the file on both branches is binary identical and at the same location, but presumably Mercurial is flagging it as a difference to be merged because they arrived there by apparently different means.
So the question then becomes:
Is there any way to retrospectively repair the move being treated as an add and delete on a long committed changeset (a new commit would be fine, but I can't edit the history) , or do I just need to let it go through in the merge?
Is there any way to retrospectively repair the move being treated as an add and delete on a long committed changeset (a new commit would be fine, but I can't edit the history)
Well... sort of. Update to the most recent Orange commit in which the files had their old names (you can use hg bisect to find it if you're not sure exactly when it happened), do hg rename to the new names, commit, and then merge this into the current Orange head. Mercurial should be smart enough to register the files as properly renamed, and it won't cause conflicts (we know this because the more complex Apple/Orange merge didn't).
or do I just need to let it go through in the merge?
This is easier. Mercurial's merging algorithm is quite smart. It can deal with situations like this just fine.
Unless you have a third branch in which the files were never moved, the second option is unlikely to cause a problem. If you do have such a branch, you should be fine as long as you merge it into a descendant of the Apple rename (or merge from such a descendant). The major difficulty would be with merges to or from the Orange branch.

Fossil SCM - Revert to a specific revision like Mercurial

While using Mercurial if I want to change the current working copy with a specific revision I just do:
$> hg revert good_revision
$> hg commit -m "Now I'm in the good revision"
Then I can see that all my files are int the good_revision state and can start working on it.
So far on fossil I can do a revert but only on specific files, not the entire repository, and update or checkout don't seem to work as I would expect.
How can fossil revert my entire repository to a certain revision?
I'm not sure I quite follow but I think what you want is to be able to create a "multiple heads on one branch" sutuation in Fossil. If yes, then Fossil does support this, just it calls branch's heads "leaves", and this process is called "forking".
To do that, you
fossil update good_revision
and then
fossil commit --allow-fork
You may now spawn fossil ui, navigate to your branch and see it having two leaves.
You now may close the then-current leaf.
Note that, while supported, this does not appear to be a recommended practice. Instead, Fossil recommends a rather peculiar approach for throwing away changes:
Rename the branch at the "bad" leaf to "mistake" (or create that branch if it doesn't yet exist). By doing this you effectively "mark" the resulting subleaf as a mistake.
Note that the name "mistake" name is just a convention; this branch does not exist in a freshly created repository.
Close the "bad" leaf.
Return to the last-good state using fossil update, continue hacking.
Since that "last-good" commit still inherits the branch tag of its parent commit, the next commit you record will also inherit it and won't be on the branch "mistake".
For an example, see how it looks in the SQLite repo—there's a bunch of assorted short chains of commits on this branch. See also this.
My slightly different solution to what I think I understand the question to be (paraphrased: how to work on an older "good_revision" than current leaf of this branch/trunk that I'll call bad_leaf, and treat changes since "good_revision" as bad), which is sort of equivalent to applying diffs between the two versions but in reverse from/to order:
Merge in a (empty) fork from the good_revision, using the baseline from the bad_leaf instead of the default, last common commit; hence the diffs that will be applied are the original branch's differences back to a good_revision fork you create as it won't see they've already been applied. Using the latest as baseline "hides" those which would otherwise make it ignore all changes as they're already applied.
fossil update good_revision
fossil commit --allow-fork --allow-empty
# note the uuid from that commit (for use as forked_basis below)
fossil merge -f --integrate --baseline bad_leaf forked_basis
Then of course once happy,
fossil commit
It doesn't create any branches that should be called "mistake", it just applies the reverse diffs from good_revision to bad_leaf into bad_leaf to put you back where you were and you can continue committing to that same (new) leaf that used to be at bad_leaf.
A diff (straight gnu, not fossil diff) against a checkout at the original good_revision compared to a checkout after the above commands matched. Except for empty directories that had lost their files, but fossil doesn't track/tidy-up dead directories anyway.
caveat: I haven't been using fossil that long and its different in several ways to the common ways I've been used to with cvs/svn/git/hg/ perforce/clearcase.
Reason for adding this answer: I found the existing answers harder to understand and wasn't sure I trusted myself to do them correctly as a result.
If I understand your question correctly, there was a problem somewhere along the development cycle and you would now like to go back one or more revisions to a known good revision and start using that. Furthermore, you'd like that revision to become your trunk. The approach in Fossil is similar to that of Mercurial:
fossil revert -r good_revision
fossil commit -m "Now I'm in the good revision"
This will replace the files in the working directory with the ones from the specified revision. The commit will commit them to whatever branch you're working on (I am assuming that it is the trunk in this example). If you don't specify the revision number, it will use the last committed version.
One of the more common usages of the revert command is to roll back a single file:
fossil revert -r good_revision my_file
(or)
fossil revert my_file_from_the_last_commit
However, as shown in the first example, leaving out the file name causes all files to be reverted. For further information please see https://www.fossil-scm.org/index.html/help?cmd=revert
Sorry for the latest response, but I just came across the question while looking for something else. I post this in case someone else is looking into how to revert to a previously committed version stored in Fossil.

Committing nested .hg folders

Forget everything you think you know about sub repositories, sub modules and what not. My problem is very simple.
I have two repositories, repoOne and repoTwo
Contents of repoTwo is only one file: DefaultConfig.txt
Contents of repoOne is:
+ repoOne
+ folderA
+folderB
+repoTwo
+.hg
+DefaultConfig.txt
Ok, now I make changes only to DefaultConfig.txt within repoOne. I also add a sibling file next to it just for fun.
I want those changes to be committed only against repoOne.
That is, repoTwo should not know about these changes what so ever, but I want repoOne to keep getting updates if it chooses to hg pull from within repoTwo. It can also commit to it from inside that folder if I choose to do so.
Why is this not possible? Why does mercurial refuse to commit .hg files? It would be so brilliant otherwise! What other versioning control system would support something like this from scratch?
GIT also suffer from this exact problem! Whyyyyy!?
I'm not entirely sure I understand what you're trying to do, but it seems to me like you just need to specify the repository root directory on the command line, which is something you can do for nearly all hg commands:
cd repoTwo
hg -R ../../.. add DefaultConfig.txt
hg -R ../../.. commit -m "Whyyyyy would I do this!?"
However, I would advise against the structure you're describing, as it will very easily become confused unless you decide to go with SubRepositories, which are considered a feature of last resort.
Update: Having played with it, this doesn't actually work, as it reports that the file is in a nested repo.
Attempting to add the file to the nested repository after adding it to the parent, results in it being marked as "removed" from the parent repository.
One possible solution would be to have the file in question being in one nested repository, and cloned to another nested repository:
+ parentRepo
+ .hg
+ nestedOne
+ .hg
+ DefaultConfig.txt
+ nestedTwo : cloned from nestedOne
+ .hg
+ DefaultConfig.txt
Something like this would mean that you could have two versions of DefaultConfig.txt, and if you make changes to one, you can pass them on to the other by means of push and pull. I'm not sure if that's what you want, but it's the closest I could get, and it's messy.
To answer your question "Why is this not possible?", there are several reasons I can think of, but the main one IMO is that if you needed something like what you're asking, then there is likely an issue with your workflow, that will cause confusion down-the-line.

Which Version control?

If a project has multiple people, say, A,B,C working together and they all edit a same source file.
Couple months later, they realize that what A has been doing is wrong and they want to roll back the file in such a way that only parts/functions/lines/... that A "touched" are removed and the work B and C did is still in the roll back version. In other words, the roll back version has only the work of B and C up to the time they decide to remove A's work.
Is there any version/source control software out there (free/commercial) can do that?
Thanks.
Git and a bit of scripting will do that. Probably a bit of hand work too, but you can resort commits using interactive rebase.
Most VCSs should be able to do this -- it's a reverse merge. In Subversion you would identify the revisions made by A and merge them in again, but the other way round. To oversimplify, this means turning line additions into line removals, and vice versa.
# Don't want revision 37 because A made it.
$ svn merge -r 37:36 path
http://svnbook.red-bean.com/en/1.5/svn.branchmerge.basicmerging.html#svn.branchmerge.basicmerging.undo
I use TFS and Git. But, there are a lot of free and open source version control softwares. You can find all the source control softwares here.
In Git, you would probably do something like
git revert `git rev-list --author=A`
[Note: completely untested.]
I bet it can (easily) be done with Monotone by using `mtn local kill_certs selector certname [certval]' command (see reference) which:
This command deletes certs with the given name on revisions that match the given selector. If a value is given, it restricts itself to only delete certs that also have that same value. Like kill_revision, it is a very dangerous command; it permanently and irrevocably deletes historical information from your database.
So, by using A's certificate, the above command will eliminate 'wrong work' done by him.

vimdiff as a merge tool

vimdiff helps in showing the diff of two files graphically and allows us to pick the changes from left to right/right to left.
The files I am dealing with are huge files and most of the differences vimdiff reports can be auto-merged except a few.As it takes lot of time to go diff by diff in vimdiff and take the action.
I would like to know if there is an option available in vimdiff that automerges the differences in left and right files as long as there is no ambiguity and leaving the conflicted resolutions similar to the tools svn merge and cvs merge tools does?
Its not possible to auto-merge the changes in two files unless we have a base copy where these two files branched and changes done separately. If an item is on one side and not on the other,it can't judge whether this item was newly added or an existing item was deleted. As there is a base copy exists while merging files in a repository, cvs merge,svn merge can auto-merge the changes.
If you use no version control, you can try diff and patch this way:
Before changing your file (say, file.txt), make a backup of the original version (file.orig).
When changed are made, make a patch-file: diff file.orig file.txt >patch.txt
Get a file which you want to merge changes to (say, file2.txt).
Use patch: patch file2.txt patch.txt
Changes will be merged, conflicted rows will be placed in a separate file.
Looks like vimdiff does not allow that. Man page says
"vimdiff - edit two or three versions of a file with Vim and show differences"
But you can have a look at Kdiff3 which lets you compare and merge.