1

Here's a git problem. I'm making a programming study review app in pure (command line) Ruby. This app allows the user to design and schedule reviews of programming tasks, manage the files in which the tasks are performed, and run the result automatically from the app. For these purposes, I don't need git when there's a single file. But most advanced and web programming tasks involve editing and using multiple files, and to manage that, I need to use git, and I'm not great with git.

In the app, the maker of these more complex "repotasks" is expected to make questions based on a git branch (of his choice) of a repo (of his choice). So I figure what this requires is that, for each repo, there is a series of branches, each of which is maintained independently of each other, and each of which is relatively stable; and the app basically checks out branches as needed to answer questions. It sounds simple...

The problems are:

  • After I make new branches (by hand, with git checkout -b branch_name) and add new files, I seem to be prevented from checking out some previous branches. For example:

    $ git checkout foobar_JS_enabled_missing_prompt error: The following untracked working tree files would be overwritten by checkout: display_nodename.html Please move or remove them before you switch branches. Aborting

  • I (think I) need to git reset --hard branches after a user finishes answering a question. But doing this seems to have inadvertently blanked a file I worked hard on in setting up a later branch. I think it's because I hard-reset an earlier branch in which said file was blank.

The git interaction the app does (mostly using ruby-git) so far is:

  • Actually create repos and branches by hand.
  • List branches for question-makers to choose from.
  • Checkout branches when they are chosen, using

    g = Git.open("data/repos/#{repo}") g.branch(branch).checkout

  • Do a hard reset of a branch that a question is based on when the user starts answering the question, using:

    g = Git.open("data/repos/#{repo}") g.reset_hard

  • I haven't done this yet, but I want to create an archive branch for each question, i.e., I want to let a question-answerer to review an old answer, then switch to the main branch for that question in order to create a new answer.

Basically, I want frozen versions of each branch, but the process (described above) seems to create unwanted interactions. I thought branches were isolated from each other automatically. What am I doing wrong? What do I need to do in order to freeze the last-committed version of each branch, regardless of what happens in other branches, while I switch frequently between branches?

UPDATE (11/18): I will leave this as a comment rather than an answer, because the question is a little obscure. I never realized that the index and tree are independent of branches. So my code actually had a few subtle bugs relating to the fact that I was letting my tree get unclean. In a couple of places, I needed to hard reset the code before letting an answerer start work on an answer, even if, most of the time, that isn’t necessary. I also needed to hard reset the code after an answerer finishes. Another thing I needed to do was to check what branch is currently checked out and switch to the right one ( I had already done this, but not everywhere I should’ve).

Seems to be working now, and I’m not able to replicate the bugs anymore.

globewalldesk
  • 544
  • 1
  • 3
  • 18
  • 2
    Index and working directory is not part of any branch. When you switch branches, Git tries to preserve uncommitted changes. If it can not do that, then it refuse checkout. You need to commit changes for them to belong to branch. – user4003407 Nov 17 '18 at 18:04
  • I actually didn’t know that. I thought each branch had its own index and if you switch back, you switch back to the old index, or something… Sir this is going to help a lot! I think I might be able to figure it out now. – globewalldesk Nov 17 '18 at 19:04
  • So, just to be clear, what is the full procedure to return to a previous branch, which has different files? Do I just commit changes and then check it out? The old state of the files and directory will be reloaded in my file system then...? I actually thought that’s how it worked, and hoped that’s how it worked…and I thought I saw evidence that it worked that way… But now I’m just confused. – globewalldesk Nov 17 '18 at 19:09
  • 1
    As far as I understand, when you checkout from `source` to `destination`, then it is check for each file: if `source` match `destination`, then keep index and work directory (with exception for initial checkout case). Otherwise, if index match `destination`, then keep index and work directory. Otherwise, if index match `source` and work directory match index, then update index and work directory to match `destination`. Otherwise, fail. – user4003407 Nov 17 '18 at 21:41

2 Answers2

0

You can save your work in stash before you switch branches. Read here .
Just before switching to other branch, use git stash.
When you come back in this branch again, you can load your work saved in stash by git stash pop.
"pop" will delete your stash after applying, you can also name your stashes, and do other stuffs like not deleting a stash after applying.

Umesh Malhotra
  • 967
  • 1
  • 10
  • 25
-1

Except to restore an old version, or if you have made an error, git reset hard has to be very very rare. The only real use of git reset is when you don't' want to save your work.

At each move between branch you have to git commit and git push (ie sent to the server) before to go away, and you have to git pull (ie get from the server) after your git checkout.

If you don't make that, you get the errors like you speak about it.

Frozen branch and no interaction are a nonsense for git. The only way to not "interact" is to finish your work properly (commit, push) and get work of coworkers properly (pull).

phili_b
  • 885
  • 9
  • 27
  • You should read the question more carefully and understand the context. Indeed I do `git reset --hard` because I don't want the user's work saved permanently. I'm using git for a purpose it wasn't originally intended, perhaps, but I think it can be made to work. – globewalldesk Nov 17 '18 at 17:09
  • "What do I need to do in order to freeze the last-committed version of each branch, regardless of what happens in other branches, while I switch frequently between branches?" -> to put `*` in `.gitignore` ? (ie ignore every file). If I understand your special use of git for your students. This only during lessons. – phili_b Nov 17 '18 at 17:20
  • I said the same thing than PetSerAl in my answer you have -1. – phili_b Nov 17 '18 at 21:14
  • Sorry, but I don’t think so. – globewalldesk Nov 17 '18 at 21:55