git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Feature Enhancement Idea.

From
Junio C Hamano <gitster@pobox.com>
Date
Sep 23, 2009, 20:08 UTC
Message-ID
<7vab0lh1an.fsf@alter.siamese.dyndns.org>
In-Reply-To
<5b5e291e0909222317q47ae36d4la470f17ec3902124@mail.gmail.com>
Deon George <deon.george@gmail.com> writes:
Show 9 quoted lines
> Like I mentioned, I can achieve some of this by the use of branches
> already, however, where it comes complicated, is when:
> * I commit a change to the wrong branch (and thus upstream will never
> see my enhancements),
> * I want to identify changes to one layer (that I went to send to
> upstream for review), without including the other layers (because it
> probably isnt relevant)
> * I want to work on more than one layer (I need to be diligent about
> pulling and merging)

I think you are getting ahead of yourself by coming up with "layers" as a solution, without really spelling out and then thinking through what problem you are trying to solve.

I think the primary scenario your itch comes from is (I am writing this down to make sure I understand where you are trying to go):

 - you would want to build your changes on top of somebody else's code;
 - while doing so it is often more convenient if you do not have to think
   about which pieces of changes should go to upstream, and which other
   pieces of changes should stay local;
 - git allows you to do this with topic branch workflow, with selective
   adding with "add -p", stashing and branch switching.
 - You can however misidentify which bits should go to upstream and commit
   to a wrong branch.  You want to reduce the chance of this mistake.
Am I following you Ok so far?

Now, how does "layers" (I understand by this word you mean the concept of "layering a worktree from one branch on top of layering a worktree from another") solve that problem? If you come up with a nice way to identify, and have the tool help you identify, "these bits belong to that layer", wouldn't that approach also apply to existing topic branch workflow by having the same logic of that magic tool to help you say "these bits should go to that topic branch"?

When the granularity of the change is per-file (your "autonomous" case), "git checkout" to switch back to your topic would already solve half of that issue.

Suppose you have mainline (origin/master) and your customization topic (custom), and file F is something that does not and will never exist in the mainline. You use your master branch as your integration testing branch. With traditional topic branch workflow, you would

    $ git checkout custom
    ... work on F and other files, test the changes to your satisfaction
    $ git commit -m 'I am satisfied on my custom work'
    $ git checkout master
    $ git rebase origin/master ;# keep up with the upstream
    $ git cherry-pick ... ;# some commits in custom that should go to upstream
    $ git merge custom ;# test merge to be thrown away!
    ... now you are on the integrated result in 'master'.
    ... test, notice breakages in F, and edit it to improve it
    ... the changes to F belongs to 'custom', not for upstream!
    $ git checkout custom ;# this will take the changes to F with you
    $ git commit -m 'I should have done this to F instead' F
    ... go back to do more work
    $ git checkout master
    ... loop forever ;-)

and after you are satisfied, you would reset the merge from custom away and offer the master that is combination of what was in the origin/master plus the "upstream worthy" bits you cherry-picked ones from your custom branch.

When the granularity is sub-file, "checkout -m custom" or "stash, checkout custom, then unstash" would help carrying the changes across branches. You would need to identify which changes you would want to commit to "custom" and which changes you would want to give to upstream by making a commit on "master" when you go back there again. The middle part of the above workflow will be slightly modified for a file G that is shared between origin/master and custom branches, perhaps something like:

    ... now you are on the integrated result in 'master'.
    ... test, notice breakages in G, and edit it to improve it
    ... the changes to G belongs to 'custom', not for upstream!
    $ git checkout -m custom ;# this will take the changes to G with you
    $ git add -p G ;# pick changes that only belong to custom
    $ git commit -m 'I should have done this to G instead'

If the "layers" logic somehow can help you automate the process of sifting your changes into these two categories (perhaps it may scan the file and knows which function belongs to "custom" alone, I dunno and care about the details at this level of discussion), wouldn't that same logic help you the same way?

Past attempts that made into the toolchest are "add -p" (and "stash -p" that uses the same mechanism) which is interactive and not automated. Maybe you can build some logic to automate it further (e.g. "changes to this function should automatically be excluded from "git add" while on 'master', but should automatically be included in "git add" while on 'custom'), and it may turn out be a good addition to the toolchest.

It also may make a good addition to the toolchest to have a tool to further simplify the branch switching explicitly initiated by the end user in the above illustrations. In some cases, such as the "autonomous" case above, you do not _have_ to go back to custom branch from the work-flow point of view (you would be committing a totally untested work to custom branch, but as long as you will revisit and retest the changes in its context, it is not a major crime at all). It would be useful if you can say, while still on 'master' branch, "I just made this fix to file F that belongs to 'custom'; commit that change alone to 'custom' branch". Written as a shell script, roughly, it would look something like:

    #!/bin/sh
    target_branch="$1"
    base=$(git rev-parse --verify "$target_branch") || exit
    shift ;# all others are paths
    GIT_INDEX_FILE=.git/temp
    export GIT_INDEX_FILE
    git read-tree -m "$1"
    git add "$@"
    c=$(echo "side commit" | git commit-tree $(git write-tree) -p "$base")
    git update-ref "refs/heads/$target_branch" "$c"

But I do not see how the concept of "layering a worktree from one branch on top of layering a worktree from another", which is the implication I get from the word "git layers", helps any of that. It seems an orthogonal concept that we can do without to solve the problem you are describing.

Previous: Johan HerlandNext: Deon George
Message 7 of 11 in “Feature Enhancement Idea.”
  1. Deon GeorgeSep 23, 2009
  2. Christian CouderSep 23, 2009
  3. Johan HerlandSep 23, 2009
  4. Deon GeorgeSep 23, 2009
  5. Ciprian Dorin, CraciunSep 23, 2009
  6. Johan HerlandSep 23, 2009
  7. Junio C HamanoSep 23, 2009
  8. Deon GeorgeSep 24, 2009
  9. Jakub NarebskiSep 24, 2009
  10. Deon GeorgeSep 24, 2009
  11. Eric RaibleSep 24, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.