diff --git a/cekit/descriptor/osbs.py b/cekit/descriptor/osbs.py
index dcd23b5..dfee1da 100644
--- a/cekit/descriptor/osbs.py
+++ b/cekit/descriptor/osbs.py
@@ -98,7 +98,6 @@ class Configuration(Descriptor):
         self.schema = configuration_schema
         self.descriptor_path = descriptor_path
         super(Configuration, self).__init__(descriptor)
-        self.skip_merging = ['container', 'container_file']
 
         if 'container' in self and 'container_file' in self:
             raise CekitError('You cannot specify container and container_file together!')
diff --git a/cekit/descriptor/resource.py b/cekit/descriptor/resource.py
index 755cd73..a694c93 100644
--- a/cekit/descriptor/resource.py
+++ b/cekit/descriptor/resource.py
@@ -18,7 +18,7 @@ from cekit.config import Config
 from cekit.crypto import SUPPORTED_HASH_ALGORITHMS, check_sum
 from cekit.descriptor import Descriptor
 from cekit.errors import CekitError
-from cekit.tools import get_brew_url, Map
+from cekit.tools import get_brew_url, Map, Chdir
 
 logger = logging.getLogger('cekit')
 config = Config()
@@ -437,10 +437,15 @@ class _GitResource(Resource):
         return os.path.basename(descriptor.get('git', {}).get('url')).split(".", 1)[0]
 
     def _copy_impl(self, target):
-        cmd = ['git', 'clone', '--depth', '1', self.git.url, target, '-b',
-               self.git.ref]
-        logger.debug("Running '{}'".format(' '.join(cmd)))
+        cmd = ['git', 'clone', self.git.url, target]
+        logger.debug("Cloning Git repository: '{}'".format(' '.join(cmd)))
         subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+
+        with Chdir(target):
+            cmd = ['git', 'checkout', self.git.ref]
+            logger.debug("Checking out '{}' ref: '{}'".format(self.git.ref, ' '.join(cmd)))
+            subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+
         return target
 
 

the git "ref:" argument should accept a valid git reference
**Describe the bug**

cekit permits specifying a git ref for a module, but this does not translate into a git ref underneath, but must actually be a tag or branch name (valid argument to `git clone -b`). It would be nicer if this could be a real git ref (e.g. be123a80c5497a595e2a997a0f1dbe14c9e3442e)

**To reproduce**

Attempt to set the git ref for an external module to a ref that is not a branch or tag name.

**Expected behavior**

Remote repository cloned and local branch set up to reference the ref  specified, even if it was a sha1-id.

 - CEKit version: 3.4.0
diff --git a/tests/test_integ_builder_osbs.py b/tests/test_integ_builder_osbs.py
index 09a181f..a717f3d 100644
--- a/tests/test_integ_builder_osbs.py
+++ b/tests/test_integ_builder_osbs.py
@@ -59,10 +59,13 @@ def run_cekit(cwd,
         return result
 
 
-def run_osbs(descriptor, image_dir, mocker, return_code=0, build_command=None):
+def run_osbs(descriptor, image_dir, mocker, return_code=0, build_command=None, general_command=None):
     if build_command is None:
         build_command = ['build', 'osbs']
 
+    if general_command is None:
+        general_command = ['--redhat']
+
     # We are mocking it, so do not require it at test time
     mocker.patch('cekit.builders.osbs.OSBSBuilder.dependencies', return_value={})
     mocker.patch('cekit.builders.osbs.OSBSBuilder._wait_for_osbs_task')
@@ -82,14 +85,10 @@ def run_osbs(descriptor, image_dir, mocker, return_code=0, build_command=None):
         b"UUU"
     ])
 
-    with open(os.path.join(image_dir, 'config'), 'w') as fd:
-        fd.write("[common]\n")
-        fd.write("redhat = True")
-
     with open(os.path.join(image_dir, 'image.yaml'), 'w') as fd:
         yaml.dump(descriptor, fd, default_flow_style=False)
 
-    return run_cekit(image_dir, ['-v',
+    return run_cekit(image_dir, general_command + ['-v',
                                  '--work-dir', image_dir,
                                  '--config', 'config'] + build_command,
                      return_code=return_code)
@@ -521,3 +520,37 @@ def test_osbs_builder_with_fetch_artifacts_file_removal(tmpdir, mocker, caplog):
 
     assert not os.path.exists(os.path.join(str(tmpdir), 'osbs', 'repo', 'fetch-artifacts-url.yaml'))
     assert "Removing old 'fetch-artifacts-url.yaml' file" in caplog.text
+
+
+@pytest.mark.parametrize('flag', [[], ['--redhat']])
+def test_osbs_builder_container_yaml_existence(tmpdir, mocker, caplog, flag):
+    """
+    Make sure that the osbs section is properly merged.
+    The evidence is that the container.yaml file is generated.
+
+    https://github.com/cekit/cekit/issues/631
+    """
+
+    caplog.set_level(logging.DEBUG, logger="cekit")
+
+    mocker.patch('cekit.tools.decision', return_value=True)
+    mocker.patch('cekit.descriptor.resource.urlopen')
+    mocker.patch('cekit.generator.osbs.get_brew_url', return_value='http://random.url/path')
+    mocker.patch.object(subprocess, 'check_output')
+    mocker.patch('cekit.builders.osbs.DistGit.push')
+
+    tmpdir.mkdir('osbs').mkdir('repo')
+
+    with Chdir(os.path.join(str(tmpdir), 'osbs', 'repo')):
+        subprocess.call(["git", "init"])
+        subprocess.call(["touch", "file"])
+        subprocess.call(["git", "add", "file"])
+        subprocess.call(["git", "commit", "-m", "Dummy"])
+
+    descriptor = image_descriptor.copy()
+
+    descriptor["osbs"]["configuration"] = {'container': {'compose': {'pulp_repos': True}}}
+
+    run_osbs(descriptor, str(tmpdir), mocker, general_command=flag)
+
+    assert os.path.exists(os.path.join(str(tmpdir), 'osbs', 'repo', 'container.yaml'))
diff --git a/tests/test_unit_resource.py b/tests/test_unit_resource.py
index 3092044..2a9bd12 100644
--- a/tests/test_unit_resource.py
+++ b/tests/test_unit_resource.py
@@ -7,6 +7,12 @@ from cekit.descriptor import Image, Overrides
 from cekit.descriptor.resource import create_resource
 from cekit.config import Config
 from cekit.errors import CekitError
+from cekit.tools import Chdir
+
+try:
+    from unittest.mock import call
+except ImportError:
+    from mock import call
 
 config = Config()
 
@@ -21,13 +27,18 @@ def setup_function(function):
 def test_repository_dir_is_constructed_properly(mocker):
     mocker.patch('subprocess.check_output')
     mocker.patch('os.path.isdir', ret='True')
+    mocker.patch('cekit.descriptor.resource.Chdir', autospec=True)
+
     res = create_resource({'git': {'url': 'http://host.com/url/repo.git', 'ref': 'ref'}})
+
     assert res.copy('dir') == 'dir/repo'
 
 
 def test_repository_dir_uses_name_if_defined(mocker):
     mocker.patch('subprocess.check_output')
     mocker.patch('os.path.isdir', ret='True')
+    mocker.patch('cekit.descriptor.resource.Chdir', autospec=True)
+
     res = create_resource(
         {'name': 'some-id', 'git': {'url': 'http://host.com/url/repo.git', 'ref': 'ref'}})
     assert res.copy('dir') == 'dir/some-id'
@@ -36,6 +47,8 @@ def test_repository_dir_uses_name_if_defined(mocker):
 def test_repository_dir_uses_target_if_defined(mocker):
     mocker.patch('subprocess.check_output')
     mocker.patch('os.path.isdir', ret='True')
+    mocker.patch('cekit.descriptor.resource.Chdir', autospec=True)
+
     res = create_resource(
         {'target': 'some-name', 'git': {'url': 'http://host.com/url/repo.git', 'ref': 'ref'}})
     assert res.copy('dir') == 'dir/some-name'
@@ -44,17 +57,14 @@ def test_repository_dir_uses_target_if_defined(mocker):
 def test_git_clone(mocker):
     mock = mocker.patch('subprocess.check_output')
     mocker.patch('os.path.isdir', ret='True')
+    mocker.patch('cekit.descriptor.resource.Chdir', autospec=True)
+
     res = create_resource({'git': {'url': 'http://host.com/url/path.git', 'ref': 'ref'}})
     res.copy('dir')
-    mock.assert_called_with(['git',
-                             'clone',
-                             '--depth',
-                             '1',
-                             'http://host.com/url/path.git',
-                             'dir/path',
-                             '-b',
-                             'ref'],
-                            stderr=-2)
+    mock.assert_has_calls([
+        call(['git', 'clone', 'http://host.com/url/path.git', 'dir/path'], stderr=-2),
+        call(['git', 'checkout', 'ref'], stderr=-2)
+    ])
 
 
 def get_res(mocker):

pip install -e .
parse_log_pytest
requirements.txt
pytest pytest-cov pytest-xdist pytest-mock pytest-asyncio
3.9
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
-e git+https://github.com/cekit/cekit.git@74df8c5258a3e843a82aa9ffa4b7c94781ee3433#egg=cekit
click==8.1.8
colorlog==6.9.0
coverage==7.8.0
docopt==0.6.2
exceptiongroup==1.2.2
execnet==2.1.1
iniconfig==2.1.0
Jinja2==3.1.6
MarkupSafe==3.0.2
packaging==24.2
pluggy==1.5.0
pykwalify==1.8.0
pytest==8.3.5
pytest-asyncio==0.26.0
pytest-cov==6.0.0
pytest-mock==3.14.0
pytest-xdist==3.6.1
python-dateutil==2.9.0.post0
PyYAML==6.0.2
ruamel.yaml==0.18.10
ruamel.yaml.clib==0.2.12
six==1.17.0
tomli==2.2.1
typing_extensions==4.13.0

name: cekit
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - click==8.1.8
      - colorlog==6.9.0
      - coverage==7.8.0
      - docopt==0.6.2
      - exceptiongroup==1.2.2
      - execnet==2.1.1
      - iniconfig==2.1.0
      - jinja2==3.1.6
      - markupsafe==3.0.2
      - packaging==24.2
      - pluggy==1.5.0
      - pykwalify==1.8.0
      - pytest==8.3.5
      - pytest-asyncio==0.26.0
      - pytest-cov==6.0.0
      - pytest-mock==3.14.0
      - pytest-xdist==3.6.1
      - python-dateutil==2.9.0.post0
      - pyyaml==6.0.2
      - ruamel-yaml==0.18.10
      - ruamel-yaml-clib==0.2.12
      - six==1.17.0
      - tomli==2.2.1
      - typing-extensions==4.13.0
prefix: /opt/conda/envs/cekit

tests/test_unit_resource.py::test_repository_dir_is_constructed_properly tests/test_unit_resource.py::test_repository_dir_uses_name_if_defined tests/test_unit_resource.py::test_repository_dir_uses_target_if_defined tests/test_unit_resource.py::test_git_clone
tests/test_integ_builder_osbs.py::test_osbs_builder_with_asume_yes tests/test_integ_builder_osbs.py::test_osbs_builder_with_push_with_sync_only tests/test_integ_builder_osbs.py::test_osbs_builder_kick_build_without_push tests/test_integ_builder_osbs.py::test_osbs_builder_kick_build_with_push tests/test_integ_builder_osbs.py::test_osbs_builder_add_help_file tests/test_integ_builder_osbs.py::test_osbs_builder_add_extra_files tests/test_integ_builder_osbs.py::test_osbs_builder_add_extra_files_from_custom_dir tests/test_integ_builder_osbs.py::test_osbs_builder_extra_default tests/test_integ_builder_osbs.py::test_osbs_builder_add_files_to_dist_git_without_dotgit_directory tests/test_integ_builder_osbs.py::test_osbs_builder_with_koji_target_based_on_branch tests/test_integ_builder_osbs.py::test_osbs_builder_with_koji_target_in_descriptor tests/test_integ_builder_osbs.py::test_osbs_builder_with_fetch_artifacts_file_creation tests/test_integ_builder_osbs.py::test_osbs_builder_with_fetch_artifacts_file_removal tests/test_integ_builder_osbs.py::test_osbs_builder_container_yaml_existence[flag0] tests/test_integ_builder_osbs.py::test_osbs_builder_container_yaml_existence[flag1]
tests/test_unit_resource.py::test_fetching_with_ssl_verify tests/test_unit_resource.py::test_fetching_disable_ssl_verify tests/test_unit_resource.py::test_fetching_bad_status_code tests/test_unit_resource.py::test_fetching_file_exists_but_used_as_is tests/test_unit_resource.py::test_fetching_file_exists_fetched_again tests/test_unit_resource.py::test_fetching_file_exists_no_hash_fetched_again tests/test_unit_resource.py::test_generated_url_without_cacher tests/test_unit_resource.py::test_resource_verify tests/test_unit_resource.py::test_generated_url_with_cacher tests/test_unit_resource.py::test_path_resource_absolute tests/test_unit_resource.py::test_path_resource_relative tests/test_unit_resource.py::test_path_local_existing_resource_no_cacher_use tests/test_unit_resource.py::test_path_local_non_existing_resource_with_cacher_use tests/test_unit_resource.py::test_url_resource_download_cleanup_after_failure tests/test_unit_resource.py::test_copy_plain_resource_with_cacher tests/test_unit_resource.py::test_copy_plain_resource_from_brew tests/test_unit_resource.py::test_overide_resource_remove_chksum
cekit/descriptor/osbs.py cekit/descriptor/resource.py
cekit/descriptor/osbs.py cekit/descriptor/resource.py