[PATCH 0/4] pacdiff: learn (M)erge mode
This series teaches pacdiff to perform 3-way merges on config files. The first commit is a cleanup that should be done regardless of whether the rest of this series is merged. The next two commits are small refactors to make final change more readable. The last patch implements the bulk of the logic. It also includes some comment requests. Denton Liu (4): pacdiff: Reindent awk script pacdiff: Implement die() pacdiff: Reduce repetition in input loop pacdiff: Learn the (M)erge mode doc/pacdiff.8.txt | 9 +++- src/pacdiff.sh.in | 102 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 97 insertions(+), 14 deletions(-) -- 2.29.2.889.g5298b911bd
The way that the awk script used for fetching files from the pacdb is
indented is very misleading. It appears as if the `print $1` is part of
the if.
Unindent the `print $1` and the following closing brace so that it's
obvious that they are part of the while.
Signed-off-by: Denton Liu
In a future commit, we will be making more use of this function. For
now, implement it and use it in the one place where it's applicable.
Signed-off-by: Denton Liu
The input loop repeats the `ask` code twice. In a future commit, we will
be introducing another instance of the `ask` code. This makes it
possible to mistakenly make the code to get out of sync.
Refactor the loop so that the `ask` code happens once at the top of the
loop. This introduces one functional change in the "Invalid answer" case
but it also makes it more consistent with the remaining cases.
Signed-off-by: Denton Liu
Currently, pacdiff only allows users to diff between the current file
and the new file. However, the merging of files could be automated by
the use of some 3-way merge utility.
Teach pacdiff the (M)erge mode which performs a 3-way merge using a
given $MERGEPROG (`diff3 -m` by default). The base file is taken from
from the second-newest package in the cache.
Signed-off-by: Denton Liu
This series teaches pacdiff to perform 3-way merges on config files. The first two commits are small refactors to make final change more readable. The final commit is what actually implements the meat of the change. Changes since v1: * Add an example of $MERGEPROG usage * Always ask user if they'd like to use merge results (I've been bitten by the lack of this feature!) * Drop refactoring patch (it's been merged) Denton Liu (3): pacdiff: Implement die() pacdiff: Reduce repetition in input loop pacdiff: Learn the (M)erge mode doc/pacdiff.8.txt | 9 ++++- src/pacdiff.sh.in | 100 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 96 insertions(+), 13 deletions(-) Range-diff against v1: 1: 7c6223d < -: ------- pacdiff: Reindent awk script 2: e377ae2 = 1: 4ddc2db pacdiff: Implement die() 3: bdbe0b2 = 2: 0a53816 pacdiff: Reduce repetition in input loop 4: cb73198 ! 3: ae12e25 pacdiff: Learn the (M)erge mode @@ Commit message given $MERGEPROG (`diff3 -m` by default). The base file is taken from from the second-newest package in the cache. - - ## Notes ## - There are a few things I'd like some comments on: - - * Is there a better way of getting the base file? I assume that - most people will run pacdiff right after an update but what if - they run pacdiff after two or more updates? - - * How is the UI flow for the merge command? Do we want to let - automerges write out without warning or do we want to do - something else? - - * When displaying conflicts, I currently display a diff against - the base and the merged version. Do we want to display a diff - against the merged and the current version? - ## doc/pacdiff.8.txt ## @@ doc/pacdiff.8.txt: Description ----------- @@ src/pacdiff.sh.in: Search Options: select one (default: --pacmandb) (default: /etc) + MERGEPROG override the 3-way merge program: (default: 'diff3 -m') - Example: DIFFPROG=meld DIFFSEARCHPATH="/boot /etc /usr" $myname +-Example: DIFFPROG=meld DIFFSEARCHPATH="/boot /etc /usr" $myname ++Example: DIFFPROG=meld DIFFSEARCHPATH="/boot /etc /usr" MERGEPROG="git merge-file -p" $myname Example: $myname --output --locate + + EOF @@ src/pacdiff.sh.in: print_existing_pacsave(){ done } @@ src/pacdiff.sh.in: print_existing_pacsave(){ + tar -xOf "$base_tar" "${file#/}" >"$base" + if $mergeprog "$file" "$base" "$pacfile" >"$merged"; then + msg2 "Merged without conflicts." -+ else -+ $diffprog "$file" "$merged" -+ -+ while :; do -+ ask "Would you like to use the results of the merge? [y/n] " -+ -+ read c || return 1 -+ case $c in -+ y|Y) break ;; -+ n|N) return 1 ;; -+ *) msg2 "Invalid answer." ;; -+ esac -+ done + fi + ++ $diffprog "$file" "$merged" ++ ++ while :; do ++ ask "Would you like to use the results of the merge? [y/n] " ++ ++ read c || return 1 ++ case $c in ++ y|Y) break ;; ++ n|N) return 1 ;; ++ *) msg2 "Invalid answer." ;; ++ esac ++ done ++ + if ! cp -v "$merged" "$file"; then + warning "Unable to write merged file to %s. Merged file is preserved at %s" "$file" "$merged" + return 1 -- 2.31.0.rc1.228.gb75b4e4ce2
In a future commit, we will be making more use of this function. For
now, implement it and use it in the one place where it's applicable.
Signed-off-by: Denton Liu
The input loop repeats the `ask` code twice. In a future commit, we will
be introducing another instance of the `ask` code. This makes it
possible to mistakenly make the code to get out of sync.
Refactor the loop so that the `ask` code happens once at the top of the
loop. This introduces one functional change in the "Invalid answer" case
but it also makes it more consistent with the remaining cases.
Signed-off-by: Denton Liu
Currently, pacdiff only allows users to diff between the current file
and the new file. However, the merging of files could be automated by
the use of some 3-way merge utility.
Teach pacdiff the (M)erge mode which performs a 3-way merge using a
given $MERGEPROG (`diff3 -m` by default). The base file is taken from
from the second-newest package in the cache.
Signed-off-by: Denton Liu
On March 4, 2021 6:55:44 AM EST, Denton Liu via pacman-contrib
This series teaches pacdiff to perform 3-way merges on config files. The first two commits are small refactors to make final change more readable. The final commit is what actually implements the meat of the change.
Changes since v1:
* Add an example of $MERGEPROG usage
* Always ask user if they'd like to use merge results (I've been bitten by the lack of this feature!)
* Drop refactoring patch (it's been merged)
Denton Liu (3): pacdiff: Implement die() pacdiff: Reduce repetition in input loop pacdiff: Learn the (M)erge mode
doc/pacdiff.8.txt | 9 ++++- src/pacdiff.sh.in | 100 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 96 insertions(+), 13 deletions(-)
Range-diff against v1: 1: 7c6223d < -: ------- pacdiff: Reindent awk script 2: e377ae2 = 1: 4ddc2db pacdiff: Implement die() 3: bdbe0b2 = 2: 0a53816 pacdiff: Reduce repetition in input loop 4: cb73198 ! 3: ae12e25 pacdiff: Learn the (M)erge mode @@ Commit message given $MERGEPROG (`diff3 -m` by default). The base file is taken from from the second-newest package in the cache.
- - ## Notes ## - There are a few things I'd like some comments on: - - * Is there a better way of getting the base file? I assume that - most people will run pacdiff right after an update but what if - they run pacdiff after two or more updates? - - * How is the UI flow for the merge command? Do we want to let - automerges write out without warning or do we want to do - something else? - - * When displaying conflicts, I currently display a diff against - the base and the merged version. Do we want to display a diff - against the merged and the current version? - ## doc/pacdiff.8.txt ## @@ doc/pacdiff.8.txt: Description ----------- @@ src/pacdiff.sh.in: Search Options: select one (default: --pacmandb) (default: /etc) + MERGEPROG override the 3-way merge program: (default: 'diff3 -m')
- Example: DIFFPROG=meld DIFFSEARCHPATH="/boot /etc /usr" $myname +-Example: DIFFPROG=meld DIFFSEARCHPATH="/boot /etc /usr" $myname ++Example: DIFFPROG=meld DIFFSEARCHPATH="/boot /etc /usr" MERGEPROG="git merge-file -p" $myname Example: $myname --output --locate + + EOF @@ src/pacdiff.sh.in: print_existing_pacsave(){ done } @@ src/pacdiff.sh.in: print_existing_pacsave(){ + tar -xOf "$base_tar" "${file#/}" >"$base" + if $mergeprog "$file" "$base" "$pacfile" >"$merged"; then + msg2 "Merged without conflicts." -+ else -+ $diffprog "$file" "$merged" -+ -+ while :; do -+ ask "Would you like to use the results of the merge? [y/n] " -+ -+ read c || return 1 -+ case $c in -+ y|Y) break ;; -+ n|N) return 1 ;; -+ *) msg2 "Invalid answer." ;; -+ esac -+ done + fi + ++ $diffprog "$file" "$merged" ++ ++ while :; do ++ ask "Would you like to use the results of the merge? [y/n] " ++ ++ read c || return 1 ++ case $c in ++ y|Y) break ;; ++ n|N) return 1 ;; ++ *) msg2 "Invalid answer." ;; ++ esac ++ done ++ + if ! cp -v "$merged" "$file"; then + warning "Unable to write merged file to %s. Merged file is preserved at %s" "$file" "$merged" + return 1
Works great, thank you, pushed. -- Best, Daniel https://danielcapella.com
participants (2)
-
Daniel M. Capella
-
Denton Liu