Coder Social home page Coder Social logo

tmt's Introduction

Temporary Merge Tool (tmt)

tmt helps you work with several feature branches at once, by generating a checkout that contains the merge of all of the desired branches, and helping you commit changes back to the relevant branch.

A use case is to develop several feature branches (or github pull requests) at once, testing all of them together, but keeping their history separate for sharing with others or merging to master.

Usage

All these commands should be run somewhere in a git checkout.

Initialise: tmt init

Show status: tmt status

Add in a branch to the current mix: tmt add <branchname> - you'll need to add two branches for this to be interesting. (eg master, and a feature branch)

Remove a branch from the current mix: tmt remove <branchname>

Commit changes you've made locally onto a specific branch: tmt on master git commit (or, tmt on <branch> <command>) tmt will switch to that branch, carrying over uncommitted changes if git is capable of doing so, run the command, then materialise the full mix again. This is especially prone to breaking (but hey, maybe all of that will get fixed?)

Force tmt to regenerate the current mix: tmt materialise

State file

.git/tmt-context is a mostly human readable files containing the branches used in the current mix, and should be safe to edit by hand when you need to repair something that tmt can't deal with. After editing, run tmt materialise to regenerate a checkout.

git rerere

tmt knows about git rerere. This can make the repeated materialisation of conflicting branches substantially more user friendly.

Turn git rerere on by typing:

git config --local rerere.enabled 1

and then fix and commit merge conflicts as before.

When a previously seen merge conflict is encountered during tmt materialise, git rerere will be used to replay the resolution, allowing the merge to complete successfully.

The user interface flow for this is a little awkward: you will see the initial git merge fail, followed by tmt fixing up the merge failure using git rerere.

Comparison to stgit

I like using stgit (https://github.com/ctmarinas/stgit) to keep different pieces of work separate (as patches) while also being able to use my local copy of a repo with several (or all) of those patches applied.

That doesn't work so well for collaborative development - stgit patches aren't themselves versioned, so are hard to share.

tmt is an attempt to get something like that workflow, but collaboratively. The equivalent to an stgit patch is a regular git branch. 'tmt' lets you combine a bunch of those regular branches into your work directory, and commit a change onto any of those branches. Regular git commands let you share those branches with other developers.

Command-line completion

bash commandline completion can be enabled by typing:

 source <(tmt --bash-completion-script $(which tmt))

In theory, completion is also available for zsh and fish using --zsh-completion-script and --fish-completion-script.

This uses the optparse-applicative library. More information on how that library handles command line completion is here: https://github.com/pcapriotti/optparse-applicative#bash-zsh-and-fish-completions

License

tmt is Copyright (C) 2018 Ben Clifford

This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License
as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA

tmt's People

Contributors

benclifford avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

tmt's Issues

`tmt add` gives spurious errors when adding non-existent branch, with `rerere` enabled

When adding a non-existent branch, git merge fails during materialise.

But with rerere enabled, a merge failure doesn't cause a materialise failure directly.

tmt asks rerere if there are any unresolved merge conflicts (which there aren't - because a merge didn't happen at all), and then tries to git commit the rerere-resolved conflicts that it assumes exist and are committable - but they do not exist.

So materialise fails, as desired, but it fails due to that git commit failing after a chain of unnecessary and confusing attempts at doing something.

Sample output:

benc@fitzroy:~/parsl/src/parsl$ tmt add benc-factor-launch
+ git config rerere.enabled
tmt: temporary merge tool
tmt: Reading context
tmt: Loaded context is: reload-configs-#549, master, mpi_executor_heartbeat, benc-doc-fiddles, benc-filescheme, origin/benc-executor-label, benc-apperrors-apptimeout, benc-apperrors-deserialisation, benc-apperrors-bad-formatting, benc-mypy-550, benc-mypy, benc-remove-timeout
tmt: Adding branch benc-factor-launch
tmt: Materialising context: reload-configs-#549, master, mpi_executor_heartbeat, benc-doc-fiddles, benc-filescheme, origin/benc-executor-label, benc-apperrors-apptimeout, benc-apperrors-deserialisation, benc-apperrors-bad-formatting, benc-mypy-550, benc-mypy, benc-remove-timeout, benc-factor-launch
+ git checkout --detach reload-configs-#549
Warning: you are leaving 5 commits behind, not connected to
any of your branches:

  e40536d3 tmt: merging in benc-remove-timeout
  188d5e9a tmt: merging in benc-mypy
  fc865e35 tmt: merging in benc-mypy-550 -- attempted rerere fix
  39f7498c tmt: merging in benc-apperrors-apptimeout
  4f8bf2dd tmt: merging in master

If you want to keep them by creating a new branch, this may be a good time
to do so with:

 git branch <new-branch-name> e40536d3

HEAD is now at 97cecabe... Correct reference to DataManager, not DataFlowKernel
Your branch is up-to-date with 'origin/reload-configs-#549'.
+ git config rerere.enabled
+ git merge --no-ff -m 'tmt: merging in master' master
+ git config rerere.enabled
+ git merge --no-ff -m 'tmt: merging in mpi_executor_heartbeat' mpi_executor_heartbeat
+ git config rerere.enabled
+ git merge --no-ff -m 'tmt: merging in benc-doc-fiddles' benc-doc-fiddles
+ git config rerere.enabled
+ git merge --no-ff -m 'tmt: merging in benc-filescheme' benc-filescheme
+ git config rerere.enabled
+ git merge --no-ff -m 'tmt: merging in origin/benc-executor-label' origin/benc-executor-label
+ git config rerere.enabled
+ git merge --no-ff -m 'tmt: merging in benc-apperrors-apptimeout' benc-apperrors-apptimeout
+ git config rerere.enabled
+ git merge --no-ff -m 'tmt: merging in benc-apperrors-deserialisation' benc-apperrors-deserialisation
+ git config rerere.enabled
+ git merge --no-ff -m 'tmt: merging in benc-apperrors-bad-formatting' benc-apperrors-bad-formatting
+ git config rerere.enabled
+ git merge --no-ff -m 'tmt: merging in benc-mypy-550' benc-mypy-550
tmt: Merge failed
tmt: Merge stdout:
Auto-merging requirements.txt
CONFLICT (content): Merge conflict in requirements.txt
Auto-merging parsl/data_provider/files.py
Auto-merging parsl/__init__.py
Automatic merge failed; fix conflicts and then commit the result.

tmt: Merge stderr:
Resolved 'requirements.txt' using previous resolution.

+ git rerere remaining
tmt: git rerere reports no remaining conflicts, so committing
+ git commit -a -m 'tmt: merging in benc-mypy-550 -- attempted rerere fix'
[detached HEAD a90f5ac1] tmt: merging in benc-mypy-550 -- attempted rerere fix
+ git config rerere.enabled
+ git merge --no-ff -m 'tmt: merging in benc-mypy' benc-mypy
+ git config rerere.enabled
+ git merge --no-ff -m 'tmt: merging in benc-remove-timeout' benc-remove-timeout
+ git config rerere.enabled
+ git merge --no-ff -m 'tmt: merging in benc-factor-launch' benc-factor-launch
tmt: Merge failed
tmt: Merge stdout:

tmt: Merge stderr:
merge: benc-factor-launch - not something we can merge

+ git rerere remaining
tmt: git rerere reports no remaining conflicts, so committing
+ git commit -a -m 'tmt: merging in benc-factor-launch -- attempted rerere fix'
HEAD detached from refs/heads/reload-configs-#549
Untracked files:
[...]
nothing added to commit but untracked files present
tmt: callCommand: git commit -a -m 'tmt: merging in benc-factor-launch -- attempted rerere fix' (exit 1): failed

Adding a branch somewhere other than the end of the stack

Sometimes I want to add a branch earlier on in the stack - in practice, for me it seems like the more likely a branch is to be merged to master, the earlier on I want it, and the more experimental/play-like the branch, the later I want it.

This might be as simple as allowed adds on the start (as well as the end) of the stack.

dynamic merge fixups can be done when there's a merge conflict, but not otherwise

When two branches being merged together conflict, there is a step involving rerere to make arbitrary changes that make the two branches work together (not just fixing the textual conflict)

When there is no textual conflict, but there is a functional conflict, that fixup step is not available -so tmt doesn't provide a place to put in such fixups.

It would be nice to have this fixup ability somehow, though I'm not sure what it would look like.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.