Say I have a locally modified file my_V1 and the newer official version of the same file: V2 , but their common ancestor V1 is gone.
And I want to merge some of changes of my_V1 into V2 in order to get a my_V2, what is the common practice to diff them, review the patch, and applying the patch.
What I am doing is mostly like
diff -U V2 my_V1 > my_patch #generate a unified patch
vi my_patch #review it
patch V2 -o my_V2 -i my_patch #apply
And when I reviewing and picking lines to merge into V2, it seems I must manually specify the new position and length of every chunk, or patch simply refuse to apply it.
Is this what we have to bear when using gnu diff?
or, am I supposed to use patch and diff in another more more elegant way?
You should have a look at patchutils, especially the filterdiff command. It can be used to review a diff and keep only some changes.
Related
Whenever I perform an hg rebase and there are merge conflicts, it immediately pulls up an editor for me to resolve the conflict. However, it doesn't give me any information about where in the rebase process I am at. For example, if my history looks as follows:
o 12
|
o 11
|
10 o |
\ /
o 9
Performing hg rebase -s 11 -d 10 may have a conflict trying to apply either 11 or 12. It is difficult to tell at a glance just from the merge conflict where I am stopped, especially when the graph is larger than this. How can I tell where in the rebase process the conflict is?
Very recent Mercurials have two configuration options: [ui] mergemarkertemplate, and [ui] pre-merge-tool-output-template, which can be used to improve this situation a bit.
pre-merge-tool-output-template
pre-merge-tool-output-template is printed before running any external merge tool. This can be used to print something before your editor or kdiff3 pops up; note that if you use a terminal-based merge tool (such as most editors unless they're the gui version), it'll likely be hidden by the merge tool. Depending on OS and what program you're using, you may be able to hit Ctrl-Z to suspend your merge tool to see this output.
Example output:
merging path/to/file
Running merge tool for path/to/file (/usr/bin/vim):
- local (working copy): 10:2d1f533d add binary file (#2) tip default
- base (base): 6:abcd1234 some other description default
- other (merge rev): 9:1e7ad7d7 add binary file (#1) default
... vim runs here ...
See https://www.mercurial-scm.org/repo/hg/file/14589f1989e9/tests/test-merge-tools.t#l1956 for the template that produced that output, hg help config.ui.pre-merge-tool-output-template and hg help templates for more information on that.
mergemarkertemplate
mergemarkertemplate controls the conflict markers you see in your editor. Set [ui] mergemarkers=detailed and see if this is sufficient; if not, you can use [ui] mergemarkertemplate to customize it; this can also be customized on a per-merge-tool basis, so see hg help config.ui.mergemarkers, hg help config.ui.mergemarkertemplate, and hg help config.merge-tools.
Programs with customizable labels
Merge tools like kdiff3 often have the ability to customizable the labels. In the default configuration, this should be the operation-provided name for the base/local/other (in my example above, this would be base, working copy, and merge rev, respectively. I believe if you have [ui] mergemarkers=detailed or [merge-tools] kdiff3.mergemarkers=detailed, these will include additional information. See hg help config.merge-tools for more information on the per-merge-tool configuration options.
(Not an answer, exactly, but a bit long for a comment...)
When you write:
Performing hg rebase -s 11 -d 10 may have a conflict trying to apply
either 10 or 11.
do you mean to write
may have a conflict trying to apply either 11 or 12
? Because you are trying to rebase those csets to 10, so it doesn't make sense to talk about applying 10. Also, consider using the Evolve extension if you aren't already. It makes everything append-only, which is much better.
Also, test in a clone. And also, try rebasing 12 first, if possible. Anyway, Mercurial is just trying to rebase the changes from both 11 and 12, and I don't think it distinguishes between those changes. And why would you expect it to? Isn't it obvious to you which changes belong to which cset?
Also, consider configuring your merge setup for use with kdiff3, if you aren't already. It makes things much clearer to do things in a merge editor, and you can also see both sides of the merge clearly. See
https://www.mercurial-scm.org/wiki/MergeToolConfiguration and https://www.mercurial-scm.org/wiki/KDiff3
Personally, I have the following lines in my ~/.hgrc, but they've been there a long time, and I don't remember where I got them from. Also, I don't do merges much these days. But for whatever it is worth...
[merge-tools]
kdiff3.args=--auto --L1 base --L2 local --L3 other $base $local $other -o $output
kdiff3.regkey=Software\KDiff3
kdiff3.regappend=\kdiff3.exe
kdiff3.fixeol=True
kdiff3.gui=True
kdiff3.diffargs=--L1 '$plabel1' --L2 '$clabel' $parent $child
Hope that helps.
I'm using Buildroot as a submodule, and I want to reuse existing in-tree defconfigs with a few modification of my own.
I'd like to store just the modified options in a config fragment, just like I can do with BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES for the Linux kernel config.
Right now I'm doing something like:
cd buildroot
make BR2_EXTERNAL="$(pwd)/../mypackage" qemu_x86_64_defconfig
echo '
BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="../kernel_config_fragment"
BR2_ROOTFS_OVERLAY="../rootfs_overlay"
' >> .config
make
Is there a nicer way to avoid that echo with a config fragment, just like I'm using for the Linux kernel config fragment? I'd expect something like:
make BR2_CONFIG_FRAG=br_config_frag
where br_config_frag contains the lines:
BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="../kernel_config_fragment"
BR2_ROOTFS_OVERLAY="../rootfs_overlay"
and then I'd be able to write just:
make -C buildroot BR2_CONFIG_FRAG=br_config_frag qemu_x86_64_defconfig all
Here's the full example repo.
Edit
One slight improvement is to put the "config fragment" in a separate file buildroot_config_fragment:
BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="../kernel_config_fragment"
BR2_ROOTFS_OVERLAY="../rootfs_overlay"
and then cat that:
cat ../buildroot_config_fragment >> .config
First side note: your script should run make olddefconfig before make, so that any new options are set to their default value instead of being asked for interactively.
You could simplify the script a little by doing:
cat configs/qemu_x86_64_defconfig br_config_frag > .config
make olddefconfig
You can also use the script support/kconfig/merge_config.sh from the kconfig infrastructure. However, that script internally uses make alldefconfig which currently doesn't work - you need a patch for that.
If you would like to add support for BR2_CONFIG_FRAG to the Buildroot infrastructure, feel free to send a patch to the Buildroot mailing list!
I asked on the IRC, and an user who seems to be Yann E. Morin, who seems to be an active developer, said it is not possible currently.
Arnout's make alldefconfig patch is now merged in buildroot as of 26 Jul 2017
(https://github.com/buildroot/buildroot/commit/dab80981d15979eab3aea28a33694396635a52a1).
This means you can now do:
./support/kconfig/merge_config.sh configs/qemu_x86_64_defconfig fragment1.config fragment2.config
This will use qemu_x86_64_defconfig as the base and add modifications given in the listed fragment config files. The tool will also show nice warnings if you override items.
I have a situation where I'd like to diff two branches in Perforce. Normally I'd use diff2 to do a server-side diff but in this case the files on the branches are so large that the diff2 call ends up filling up /tmp on my server trying to diff them and the diff fails.
I can't bring down my server to rectify this so I'm looking at checking out the the content to disk and using diff on the command line to inspect and compare the content.
The trouble is: most of the files have RCS keywords in them that are being expanded.
I know can remove keyword expansion from a file by opening the files for edit and removing the -k attribute from the files in the process, but that seems a bit brute force. I was hoping I could just tell the p4 sync command not to expand the keywords on checkout. I can't seem to find a way to do this? Is it possible?
As a possible alternative solution, does anyone know if you can tell p4 diff2 which directory to use for temporary space when you call it? If I could tell it to use abundant NAS space instead of /tmp on the Perforce server I might be able to make it work.
I'm using 2010.x version of Perforce if that changes the answer in any way.
There's no way I know of to disable keyword expansion on sync. Here's what I would try:
1) Create a branch spec between the two sets of files
2) Run "p4 files //path/to/files/... | cut -d '#' -f 1 > tmp"
Path to files above should be the right hand side of the branch spec you created
3) p4 -x tmp diff2 -b
This tells p4 to iterate over the lines of text in 'tmp' and treat them as arguments to the command. I think /tmp on your server will get cleared in-between each file this way, preventing it from filling up.
I unfortunately don't have files large enough to test that it works, so this is entirely theoretical.
To change the temp directory that p4d uses just TEMP or TMP to a different path and restart p4d. If you're on Windows make sure to call 'p4 set -S perforce TMP=' to set variable for the Perforce service; without the -S perforce you'll just set it for the current user.
Is there a way to ask Mercurial to read most/all of the commands, options, and arguments that I want to give it from a response file, instead of passing them on the command line?
For instance, instead of this:
hg commit -m "commit message" --INCLUDE file1 --INCLUDE file2 ...
I would create a text file containing
-m "commit message" --INCLUDE file1 --INCLUDE file2 ...
and then ask Mercurial to read it with this (hyphotetical) syntax:
hg commit #responses.txt
The reason I'm asking is that I'm creating a wrapper library for .NET around the Mercurial command line client, and this question on SO got me worried that the length of the command line might be a problem for me at some point: “Resulting command line for hg.exe too long” error in Mercurial.
There isn't a built-in way to do this as far as I know, but I think there is a way you can build what you need.
Use the Mercurial internal API and write your own wrapper script. Rather than trying to get it to read any and all commands and options, it'll be a lot easier to stick to your specific goal (i.e. "commit" and the options you need).
(Note the warnings on the API page. If this wrapper you're building is going to be distributed to other people, look into the licensing issue and have a plan for how to handle future Mercurial upgrades, which may break your wrapper.)
Here's a kludgy workaround...
Create a dummy, empty response file in the repo's .hg directory, for example .hg\response.
In the repo's .hg\hgrc, add the line
%include response
Before doing any repository operations, write the command line options to this response file. Use the [defaults] section to (I know it's deprecated) to specify your options.
[defaults]
commit = -m "This is a commit message" -I file1 -I file2 ...
(According to Microsoft's support, the maximum command line is 8,191 characters on XP and later. Might be useful to know if you even need to use this trick.)
Short version:
After branching in P4, how can I find out the "source" changelist of the branch?
Long version:
Let's say I have a main branch of my project at
//project/main/...
The latest changelist submitted here is #123, when I decide to create a branch for release 1.0 in
//project/1.0/...
From P4V, a new changelist is created (say #130), resolved and submitted.
From the CLI, it would look something like this:
p4 integrate -c 123 -o //project/main/... //project/1.0/...
p4 submit
Later, I look at the changelists under //project/1.0, and see the #130 changelist containing a lot of branched files.
How can I find out the changelist no. that this was originally branched from (that is, #123) ?
p4 changes will display a list of submitted changelists, optionally filtered to a specific path.
p4 changes //project/main/...
Change 123 ... 'Very last change.'
Change 122 ... 'Next-to-last change.'
Change 100 ... 'Only two changes to go...'
...
No surprise there, but, as you've found, p4 changes is less helpful when you integrate all those changes in a single change:
p4 changes //project/1.0/...
Change 130 ... 'Integrated everything from main.'
The trick is to use the -i option which includes any changelists integrated into the specified files.
p4 changes -i //project/1.0/...
Change 130 ... 'Integrated everything from main.'
Change 123 ... 'Very last change.'
Change 122 ... 'Next-to-last change.'
Change 100 ... 'Only two changes to go...'
...
To get exactly what you want (123) you'll need to write a script which filters the output from p4 changes -i //project/1.0/... to remove any change listed by p4 changes //project/1.0/... (and then take the most recent remaining change).
(When exploring, I frequently also find the -m max option useful. This limits changes to the 'max' most recent. This helps your output not flow offscreen when there are many changes.)
I don't know of any simple command that performs what you would like to do. If you are willing to script a little bit and the command doesn't have to execute fast you could perhaps try to script something like the following for all branched files:
Find the source file/revision for a target file.
p4 filelog //project/1.1/foo.bar#1
//project/1.1/foo.bar
... #1 change 6416 branch on 2009/07/10 by foo#bar (text) 'Release 1.1'
... ... branch from //project/main/foo.bar#1,#2
Get the change list at which the source file/revision was submitted.
p4 fstat //project/main/foo.bar#2
... depotFile //project/main/foo.bar
... headAction edit
... headType text
... headTime 1201771167
... headRev 2
... headChange 5353
... headModTime 1201770971
Repeat for all files in branch and select the highest change no (headChange above), which should be the latest change submitted to the parent before branching for that specific file. You could get a complete listing of all branched files using e.g. "p4 files //project/1.0/...#1".
(or perhaps take the easy way out and ask Perforce support)
Since none of the answers thus far provide the code for finding the source or root changelist of a branch, I thought I'd provide a one-liner to do just that. This approach is based on #Cwan's suggestion, and will print the "parent" changelist from which the branch was created. The FIRST_BRANCH_CL argument needs to be replaced with the branch creation changelist (i.e. the first changelist submitted to the new branch). As a concrete example, replacing FIRST_BRANCH_CL with 130 from the original question, this one-liner would output 123.
p4 describe -s FIRST_BRANCH_CL | perl -lne 'if(/^\.\.\. (.+#[0-9]+) .+$/) {print quotemeta $1}' | xargs p4 filelog -m1 | perl -lne 'if(/^\.\.\. \.\.\. branch from (.+#[0-9]+)/) {print quotemeta $1}' | xargs p4 fstat | perl -lne 'if(/^\.\.\. headChange (\d+)/) {$MaxCL=$1 if($1 > $MaxCL)} END {print $MaxCL}'
Short answer:
Use the Revision Graph in P4V is step back through time and investigate the integration history. Video on the Perforce website.
I have successfully used the revision graph on branches with thousands of files to track when an particular change was integrated into a branch. That is why I recommended it and linked to a training video as most people under-estimate it because they do not know how to use it.
Long answer:
... [Removed]
UPDATE: As the Revision Graph apparently is unfeasible, you can perhaps solve this using a process/policy, i.e., when you perform the integrate, add a note in the description "Branched # CL 123". We used this approach ourselves when integrating from a trunk to release lines.
If you use the history tab in p4v it will show you all changelists submitted against a branch, so look at this for
//project/1.0/...
once you have found the oldest submitted changelist, then on any one the files in that changelist view the Revision Graph for it, this will show you the branch that the file (and the rest of the files) were integrated from.
I'll see if I can come back with the p4 commands to do the same thing.
Updated Answer: I think this will work. Try this:
p4 interchanges from_branch to_branch
This will show unintegrated changes from your main branch to your release branch. I believe you can use the top changelist number minus 1 to find your source changelist. interchanges is an undocumented Perforce CLI feature. To find out more, type p4 help interchanges to find out more about this command.
Again, I think this will work. There may be some special cases where it will not, but it's my best guess to a tough and important problem.
"p4 integrated" worked for me. Look for "copy from" in the description