How to work with one file in GIT, but on two different branches, where I can easily switch between 2

Is there a way to work with the same file, but with different functions / branches in GIT? I am sure there is a way, but which is easier? I do not want to apply my changes, because it is cumbersome. With SVN, I was able to work on two separate branches as two different entities without any intervention and easily switch between them.

+7
git svn
source share
5 answers

use git worktree.

git worktree

Git worktree was introduced in 2007 in the contrib folder in the git repository and was called new-workdir .

In Git V2.5, it was called worktree , and it allows you to have multiple instances of the same repository in different folders.

eg:

 git worktree add <second path> 

will create another folder on your computer that allows you to work on different branches at the same time.


If you want to delete the working line, use the prune subcommand

prune
Trim work tree information in $ GIT_DIR / worktrees.

Another way to delete this is to delete the .git/worktrees

enter image description here


If later you use rebase:

  • Note: ( Since git 2.7 )
    you can also use git rebase [--no]-autostash .
+13
source share

You seem to be fixated on wanting to do it in Subversion mode. I can understand that; changing development habits can be a long process, and to some extent it may be better to bend tools for your own habits; it's fine. So, let's go:

Think of it this way: with svn you have one big directory tree where the “branches” are not first class entities, but (technically) arbitrary subdirectories

 mystuff/trunk mystuff/branches/feature1 mystuff/branches/feature2 ... mystuff/tags/1.0 mystuff/tags/1.1 ... 

So, if you use this and are happy with it, then the same solution is possible with git , checking different copies of the repository with one (not git) parent:

 mystuff/master mystuff/master/.git mystuff/feature1 mystuff/feature1/.git ... 

This is conceptually exactly the same as before. You constantly keep different repositories in your respective branch. You will have a common ancestor that, as usual, will push / pull in / out to merge (note that this can be processed locally, it does not need a physically remote location, if you do not have one, you can also / theoretically use the master repository directly as origin ).

What you don’t get, and will never succeed with git , makes changes in different branches at a time (under one “commit”). A "branch" in git is a fundamentally different thing than in Subversion, the same thing as a "commit" in git is fundamentally different here (commit! = Revision). You will have to wrap your head around it, not a single tool will save you from this.

Some operations:

  • Create a new feature2 function feature2 (starting with master ):

     mystuff> git clone {URL-or-filesystem-path-of-common-origin-repository} feature2 mystuff/feature2> git checkout -b feature2 
  • Combine your work with a branch on master :

     mystuff/feature1> git add ... ; git commit ... mystuff/feature1> git push mystuff/master> git fetch mystuff/master> git merge origin/feature1 

    The same goes for any other mergers; the master branch is technically no different from any other branches in git , it's just a naming convention (for example, /trunk is a naming convention in Subversion).

  • Get rid of the branch:

     mystuff/feature1> git push origin :feature1 # deletes the branch on the common repository mystuff> rm -rf feature1 

All this requires more hard disk storage than necessary; There are advanced methods for local cloning of the repository, reuse of object storage. Let me know in the comments if this is important to you; if you really have no space limitations, I honestly would not bother.

+1
source share

I do not want to discard my changes, because it is cumbersome.

The best way you could do this is to simply edit the file on both branches.

The idea would be to have a common base on your main branch and add a function for each branch, given your use case.

+1
source share

From what I understood from the comments section: this is what you want to have two different "versions" of the same file. (As you mentioned in the comments, the file.txt file has the line "AAAAAAA" on one and "BBBBBBB" on one, but not "AAAA").

This can be achieved by branching very easily.

Before you begin, you will be "standing" on the same branch (possibly master ). You can at this moment create a new branch git checkout -b feature1 (This command creates and switches you to the function of branch1). where you make some changes to the .txt file. Say you write "AAAAAA". Then you have to do it. git commit -a -m "Added the AAAA line" . If you are now git checkout master (you will return to the master). Your file will NOT say "AAAAA", you can make other changes to this file (either on this branch or on another branch). You can write "BBBBBBBB" to this file, and you will have 2 "versions" of the same file "file.txt", each will have "AAAA" (the one that is in the branch1 function), and the other on master will have BBBB .

Note. I created a script in which you have not changed the file initially, but if there is, there are also ways to achieve this by branching. You must def read https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging

+1
source share

I think your workflow may depend on how slow branch switching happens in SVN. In Git, you don’t need to worry about this - checking out a new branch will take part of a second (maybe a few seconds for very large projects).

It would be most reasonable for you to work on a separate branch, and as soon as you make some commits, cherry-pick them in another branch. Example: (suppose you want to work with the f.txt file, which is identical on both branches)

 $ git fetch $ git checkout branch-1 # assuming remote branches exists already $ vim f.txt # do some editing $ git commit -am "f file changed" $ git checkout branch-2 $ git cherry-pick branch-1 # <- this will pick single last commit from branch-1 # and apply it to branch-2 

You are not limited, for example, to the choice of the last commit - you can select with the identifier commit, a tag, you can use the ~ operator to select commit ancestor, etc. You can even do a lot of cherry kilos at a time by reloading or, even better, an interactive reboot.

After completing your work, you need to make two separate clicks on each branch (or you can change the push.default configuration push.default to matching to make one click from all local branches).

0
source share

All Articles