1

For a personal project where I'm the only one creating code, I sometimes switch between two different IDEs. As such, the source code is stored locally in two different places. I would like to have a history/backup of the code on Bitbucket. Is Git able to handle this?

I have foo.cpp in the directory source_code. I do not want to copy everything from the remote repo into source_code. After adding and committing foo.cpp I try to run git push origin master and it gives the error

 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'https://bitbucket.org/...'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Like it recommends I do git pull origin master but it errors with

error: Pulling is not possible because you have unmerged files.
hint: Fix them up in the work tree, and then use 'git add/rm <file>'
hint: as appropriate to mark resolution and make a commit.
fatal: Exiting because of an unresolved conflict.

What exactly does unmerged mean in this context? How can I find specifically what files are the issue? I'm guessing the problem is I have files with same name but I only want one specific file tracked from the directory. Such a simple task I would expect to be easy.

When I do git status it gives

You are currently rebasing branch 'master' on '930b2f7'.
  (fix conflicts and then run "git rebase --continue")
  (use "git rebase --skip" to skip this patch)
  (use "git rebase --abort" to check out the original branch)

Unmerged paths:
  (use "git restore --staged <file>..." to unstage)
  (use "git add <file>..." to mark resolution)
        both added:      foo2.cpp

Bitbucket's version of foo2.cpp was correct so I deleted the local one.I then ran $ git restore --staged foo2.cpp which worked. Now git pull origin master works. But still I can't push.

 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'https://bitbucket.org/...'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart. Check out this branch and integrate the remote changes
hint: (e.g. 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Again, all I'm trying to do is add a file to the master branch on the remote repo. (Aside, is "remote repo" even the right term to use to refer to a specific project on a hosting service such as Bitbucket?)

Also it says (master|REBASE 2/3) which I have no clue what it means.

LightCC
  • 9,804
  • 5
  • 52
  • 92
northerner
  • 756
  • 5
  • 21
  • 2
    If you are still in the middle of a rebase operation, run `git rebase --continue` to resume the rebase. – Greg Burghardt Aug 02 '20 at 20:03
  • 1
    Also, make **darn** sure you are not rebasing previously pushed commits from master. – Greg Burghardt Aug 02 '20 at 20:04
  • What do you mean that you are "switching between two IDEs" stored locally in two different places? Does that mean you have two copies of the repo locally, one for each IDE? – LightCC Aug 02 '20 at 20:39
  • Q: "says I need to pull but already did..." A: It's saying exactly what it means: your remote isn't correctly in sync with your local repo :( LightCC gave an excellent reply. Please be sure to "upvote" and "accept" if you found it useful. More importantly: please be sure to READ it. Please adapt your [git workflow](https://www.atlassian.com/git/tutorials/comparing-workflows) accordingly. And please post back if you have further questions. – paulsm4 Aug 02 '20 at 21:29
  • @LightCC I mean I use a heavy weight IDE for most of the code but sometime prefer Notepad++ for small drivers/experiments. The files created from Notepad++ are in a different directory than those created by the IDE. – northerner Aug 02 '20 at 23:39
  • If it's just in a different folder, that shouldn't affect Git - unless I'm missing something just save all the folders to the same folder structure and have Git encompass it all, assuming it is one larger project. If you need modularity, then make each driver/experiment a separate repo. If you make multiple repos, have multiple remotes, and share any code directly using the filesystem locally. NOTE: Another strat can be to create a separate branch for each of your experiments, and just swap between them. You can pull code from any commit/branch directly into the working directory. – LightCC Aug 03 '20 at 00:10
  • It's saying that since I deleted foo2.cpp there are unstaged changes and can't pull. I don't want to delete foo2.cpp from the remote server. How can this be fixed? – northerner Aug 03 '20 at 08:07
  • git keeps adding `<<<<<<< HEAD` and `>>>>>>> initial commit` to lines inside foo2.cpp – northerner Aug 03 '20 at 09:16
  • The `<<< HEAD` etc. is an intermediate merge version of that file. You are stuck in a merge/rebase. If you reset --hard to the latest commit it will just restore all the files and undo the merge, but otherwise do some research on how to abort a merge in progress. Depending on what you've done to try and fix it (who knows what state it's in at this point), it's hard to give direct advice beyond just temporarily save any files you want to keep out to another folder and do a hard reset to the last commit. – LightCC Aug 03 '20 at 14:13
  • @LightCC I did a `git push -f origin master` and lost most of the files and their commit history from Bitbucket. Can this be undone? – northerner Aug 04 '20 at 08:40
  • Unfortunately, force pushes are permanently replacing the remote repo with the local repo, so no. I realize it doesn't help now (sorry), but train yourself to never force push without double and triple checking that you know exactly what is going to happen, and asking yourself if the problem can be fixed with new commits that revert the changes instead. – LightCC Aug 04 '20 at 14:45
  • The answer here fixed the problem https://stackoverflow.com/questions/63242200/how-to-get-back-deleted-files-after-forced-push/63242397?noredirect=1#comment111847496_63242397 Git is far too dangerous to use on important files without being certain of what each command does. How does one learn it safely? – northerner Aug 04 '20 at 20:59
  • @paulsm4 it's normal to develop with an IDE. I use Netbeans. The path to the source code looks like `C:\Users\\Documents\NetBeansProjects\` and I'm guessing other IDEs have similarly complex paths. Do most people setup git at this location, i.e. do they go into the project directory and run `git init` and then run all subsequent git commands in this location for the project? If no, then what is a correct workflow? – northerner Aug 04 '20 at 21:04

2 Answers2

2

Git is Good.

Git works very hard to ensure the integrity of your baseline, and of your baseline's history.

You just had a Series of Unfortunate Events, I'm sorry to say :(

You also brought up a couple of good questions:

  • Q1: It's normal to develop with an IDE. I use Netbeans. Do most people setup git at this location, i.e. do they go into the project directory and run git init...?

    SHORT ANSWER: You'll generally let the IDE create your local repo for you

  • Q2: Git is far too dangerous to use on important files without being certain of what each command does. How does one learn it safely?

    SHORT ANSWER: Experiment with some "hello world" projects and a good Git tutorial; you can always make backup copies of your project as you do so.

SUGGESTIONS:

  1. Using Git with your IDE:

    • By all means, use your IDE (e.g. Netbeans). I happen to mostly use Eclipse for Java, and MSVS for Windows).
    • I would create your projects and initialize Git, all in the IDE.
    • Assuming you're on Windows, I would also download and install either/both of:
    • You'll discover that you can use ANY of these Git clients, in ANY combination, with your work.
  2. Git is completely agnostic about which client(s) you use.

    Once you've started a project and downloaded one or both of the "other" Git clients, browse to your project's directory and satisfy yourself they're all "seeing the same thing".

  3. Familiarize yourself with some basic Git workflows

    • Once you've created your project, find a good tutorial and start playing with Git features. Locally, and/or with Github or BitBucket.

    • Checkin, checkout, push, pull, "reset --hard", create branches, merge branches, etc. etc.

    • Each step of the way ... "cd" to your project's physical directory ... and make a secondary copy. Once you gain confidence, you'll discover this "extra backup" is unnecessary. Until then, it can be a lifesaver :)

    • Always remember that at any time, for any reason, as long as you have your hidden ".git" subdirectory, you can always restore your latest commit:

      git reset --hard

'Hope that helps...

paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • What you're saying is it's common to use the Git features built into an IDE, and to also use Git clients on the same files? Do I understand correctly? – northerner Aug 05 '20 at 19:34
  • Yup - that's exactly what I'm saying. In practice, this means a) you can use the IDE's built-in tools (thus saving a few keystrokes, and adhering to whatever conventions the IDE encourages), but b) you can always use other Git clients as needed :) I'm also suggesting you can and should work through some tutorials and do some "experiments" to better familiarize yourself with how Git works ... lest you experience another "Series of Unfortunate Events" ;) – paulsm4 Aug 05 '20 at 20:06
  • If I have a folder that git is tracking (e.g. ran `git init`) is it safe to drag and drop it to another location? Or would this break git? – northerner Sep 01 '20 at 11:35
  • 1
    Everything (*EVERYTHING*) needed for a git repo is contained in the hidden folder ".git". So yes, you can safely drag/drop your directory (e.g. "MyProject") safely ... as long as you *ALSO* make sure you include the ".git" subdirectory. – paulsm4 Sep 02 '20 at 00:25
1

The local and remote repos must have the same files for a commit

The answer to your first question is that yes, Git can handle having multiple local repos - but it appears you are not using Git the way it was designed to be used - so it will be difficult to help you resolve this issue, or at least you would be better off changing your workflow if you want to do this with Git.

Let me explain:

I have foo.cpp in the directory source_code. I do not want to copy everything from the remote repo into source_code.

I'm assuming by "remote repo" you mean the repo on the remote server - i.e. Bitbucket. In Git, there is no such thing as having a local copy of a remote repo that has fewer files for a given commit. When you clone a Git repo, you get all the files. In fact, normally, all the files with all the commits/history. That's actually the point of Git - to version control all your files, so you can recreate an exact copy of all the files from any commit on any PC.

If you just want to update foo.cpp in the repo, just change foo.cpp, add it to the index, and push it back up to the remote. The new commit will still have all the other files, with just foo.cpp changed in the new commit.



How to get out of the current situation?

You can get out of the rebase/merge by doing a hard reset to the latest commit in your local repo. This will reset things to start again. But I don't think you will be able to work as you wish and still keep things in sync.

When you fetch and attempt to rebase, fast-forward, or merge, Git will get confused if you delete files because you don't want them on the local repo, but they exist in the remote - thus the errors you are getting



Multiple local repos?

I'm not sure why you would want to have different local repos for different IDEs, but you CAN do this if it is really needed. Just clone the repo twice into different directories.

Just realize that whenever you push up to the remote from one of the locals, it will look just like another user pushed to the remote from the other repo. You will need to fetch those changes and fastforward/merge (a git pull is a combined git fetch and git merge) in the other local repo to incorporate them. If you update both local repos independently, you will eventually end up with merge conflicts, if they edit the same files. However, if you always "hand off" between repos by pushing up from the one, then pulling down before working on the other, that should never happen.



Consider just using one local repo (or multiple remote repos)

However, I would question why you would want two separate repos locally, for "different IDEs". I would really examine your reasoning for setting things up this way - there is likely a better workflow.

You should be able to work out of a single local repo that has all the files needed by either IDE. If you really need different files and need to manage them separately, consider making completely separate repos for them. There are various techniques that can be used to share the common files between the two repos, such as sub-modules of a third repo as a library that has the common files.

We would need more details on the purpose of using two separate IDEs in the same repo to give an answer on best practices to how to accomplish that with Git. For example, is one setup for development, and the other for release? (That would be a great separate StackOverflow question...)

LightCC
  • 9,804
  • 5
  • 52
  • 92
  • `there is no such thing as having a local copy of a remote repo that has fewer files for a given commit` can the local repo be split between two directories, so that the combined files from both of them would have all the files in a given commit? – northerner Aug 03 '20 at 03:38
  • I mean I know I can "manually" solve this problem by going into Bitbucket's web interface and adding foo.cpp there. – northerner Aug 03 '20 at 03:40
  • No, that's not the purpose of git. What you are describing is two different repos. You can share the files locally if some are the same, or formally you can create a separate repo for just the shared stuff and make that a sub-module in each of the two repos. Or you can hack it with different files in separate branches. That's probably better when they are just prototypes/experiments... (i.e. if they are temporary cases, use a branch, if permanent, use another repo). – LightCC Aug 03 '20 at 14:06