Project databases: Git. Commit. Pull. Push & more

In a previous blog post, we introduced you to Git (a version control system) and Github (a cloud-based hosting service) and how you can share your 4D code with other developers. In this blog post, we’ll go a bit further by exploring some scenarios a developer may encounter, such as cloning a remote repository, ignoring already committed files, and solving merge conflicts.


Before going any further, we assume you know how to create a project database or convert a binary database into a project. Having Git installed on your machine and an account on Github are mandatory. If you don’t already have them, please refer to this blog post to learn how to proceed.

Clone a remote repository 

It’s time to resume work on our application. But for some reason, you don’t have the project we worked on last time on your machine. What to do?

Since we created a repository on GitHub (previous blog post), it exists as a remote repository. Now we need to create a local copy on our machine and synchronize between the two locations. How to proceed?

  1. Connect to your Github account,
  2. Navigate to the main page of the repository,
  3. Click the “Clone or download” button, then click the clipboard icon (as shown in the image below):
  4. Open a terminal and indicate the location where you want to clone the directory
  5. Type git clone and paste the URL you copied in step 3.



Congratulations! You’ve created a local copy on your machine.


I don’t want git to track a particular file or folder

Sometimes, we have files or directories in our project that we don’t want tracked. That’s where a .gitignore file comes in handy. As the name indicates, it instructs Git which files, directories, or patterns to ignore in the repository.

In our case, we want Git to ignore the Data folder (which contains the journal, preferences, .4dd, and the DerivedData folder).  

  • Create .gitignore


  • Configuring ignored files/folders


.gitignore uses globbing patterns to compare file names. You can construct your patterns using various symbols. For example to ignore a folder, we append a slash at the end of the folder name. You can refer to this article to learn more about .gitignore patterns.

Ignore files that have already been committed to the repository

Keep in mind that when you create a new repository, you should also create a .gitignore file for any file patterns you want to ignore. However, there are times when files slip through that you later want ignored.

Don’t panic! In just a few simple steps, you can clean up your repository and make sure these items are ignored:

  1. Stage files for removal, but leave them locally: git rm -r –cached 
  2. Inspect the entire working directory looking for any new, deleted, or modified files and add them to the index: git add 
  3. Send the files in the staging area to the local repository: git commit -m “Clean up ignored files”
  4. Send the changes to the remote repository: git push 


Voilà! You can verify in the remote repository and that the files aren’t there!

Important note: Ignored files remain in the repository history. This is why when creating new repositories, you should also create .gitignore files indicating all of the files, folders, or patterns that you want to ignore. Otherwise if you don’t want certain files kept in the history, you’ll need to delete the repository from Github and push it again.

How to Solve merge conflicts 

First of all, STAY CALM!

When multiple developers are working within the same version control system, managing eventual conflicts becomes an everyday task. There are several options available. The conflict can be easily resolved using the 4D editor, but because all of the files are now text-based, you could also use a text editor to manually resolve the conflicts. Additionally, there’s many merge tools available which can be integrated into GIT. In the example below, we’re using the 4D editor to resolve the conflicts.

Let’s take a look at a conflict using a 4D method. In order to do this, it’s necessary to simulate a secondary user / local git repository by duplicating the database folder and making sure it has at least one project method. Now there’s  two database folders: my4DApplication and my4DApplication2. Next, open both of the applications.

    1. Open the project method in the first application, and add some content (a comment, for example).blank
    2. If you run git status, changes in the method will be detected. Commit and push the new changes.
    3. Scenario: someone else modifies the same method, at the same time . Let’s simulate this by opening the same method in the second application and modifying it with a different comment.blank
    4. Commit and push the new changes. As you can see, the push is rejected and a pull is suggested instead:blank
    5. Running the suggested git pull isn’t helping:



Now what?

Open the method with the conflict. The line with Head indicates local changes and the line in red indicates the number of the commit made by the other user.



Resolving the conflict is easy, simply select the correct parts of the code an push the changes. In this case, I’m keeping both ALERT messages with different comments:



Once this is done, the other user can run git pull to get the new changes. Both users now have the same content in the method.


To avoid conflict in the first place

There’s no sure fire way to avoid conflicts all the time, but running git fetch can save you a load of merge headaches. It checks if the remote repository has any new commits. Not doing so before trying to push caused the [Rejected] error.

To Conclude

In this post, we discussed different scenarios a developer is likely to encounter when working with Git. In an upcoming post, we’ll break away from the command line and show you how to use a GUI client to work with Git.


• Product Marketing Manager • Intissar joined 4D in 2017 as a Product Marketing Manager. She works closely with the product, marketing, engineering, and technical support teams to highlight the ‘why’, the ‘how’, and the ‘what’ of new and updated features to different audiences. This close proximity allows her to craft messaging frameworks and write in-depth content and code samples for the 4D blog and website. After graduating with an engineer's degree in Computer Science from VINCI university, Intissar worked in several startups as a software engineer. Her hands-on experience includes software specification, design, and development, user training and support, and team management.